Skip to content

v18.0.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 22:00
· 7 commits to main since this release

v18.0.0 — serving openly stops being the default

A procedure that does not name who may call it is refused. A subscription that does not name who may deliver to it
is refused. A streaming procedure is held to the same rule as its unary twin. A service that means to serve anyone
says open, explicitly, and its log says so.

Breaking for every service and caller built on 17.x, here and in every SDK. Detail in
CHANGELOG.

Also in this cut: a peer that stops granting flow-control credit on one stream no longer stalls the whole station
link; a distribution tunnel's subscription names the one node it was negotiated with instead of accepting any
publisher; and the suite reads line coverage against a floor that only goes up.

What each SDK does today

The rule above is the BEAM library's. The six SDKs are not rebuilt on 18.0.0 yet, and each still serves a streaming
procedure with no policy open, silently — the native library serves any caller and nothing in the consuming
app's code says so. One issue per SDK, each with the file and line:

SDK Where Today
macula-go#57 pool/serve.go:44, :71 — pool.Offer.Policy a nil policy serves any caller
macula-rust#53 src/pool/serve.rs:53-65 — Offer::stream sets policy: None
macula-py#18 src/macula_py/pool.py:746 — serve_stream policy: Policy | None = None
macula-dotnet#24 src/Macula/Served.cs:181 — ServeStream AuthPolicy? policy = null
macula-php#19 src/Pool.php:321 — serveStream ?ServePolicy $policy = null
macula-ts#27 src/pool.ts:398 — serveStream options.policy?

A service on any of them that means to serve anyone is served by the native library either way; a service that does
not mean that should name a policy once its SDK admits one. Until then the gap is real and written down, per SDK,
rather than left to be discovered. The SDKs move one at a time; the BEAM library moved in this release.

What each SDK does today with sources

The library now asks a subscription who may deliver to it. sources is required — members,
{org, Org}, {nodes, [NodeId]} or an explicit open — and a subscribe that names none is refused
{error, {sources, required}} rather than served open. No SDK has this yet: every one of the six takes
a realm and a topic and nothing else, so no line in a consuming app decides who may deliver, and no
check runs.

SDK Where Today
macula-go pool/pubsub.go:51 — Pool.Subscribe Subscribe(realm, topic): nowhere to declare
macula-rust src/pool/pubsub.rs:66 — Pool::subscribe subscribe(realm, topic): nowhere to declare
macula-py src/macula_py/pool.py:641, :648 subscribe(realm, topic), straight to the C ABI
macula-dotnet src/Macula/Pool.cs:375, :382 Subscribe(realm, topic), straight to the C ABI
macula-php src/Pool.php:218, :222 subscribe($realm, $topic), straight to the C ABI
macula-ts src/pool.ts:348 → addon/binding.cc:750 subscribe(realm, topic, onEvent), straight to the C ABI

Four of the six reach the mesh through one C ABI, and that ABI has no field to carry the declaration:
macula_pool_subscribe(pool, realm, topic, err_out) takes no options at all (cabi/macula.h:207; the
bindings repeat it at abi/macula.h:207 in macula-py and macula-php, at
src/Macula/Native/Libmacula.cs:204 in macula-dotnet, and as the call at addon/binding.cc:750 in
macula-ts). The ABI is macula-go's own — its header says so in its first line — so the order is fixed:
macula-go's pool grows the gate first, a new macula_pool_subscribe_opts carries it (a new function does
not change MACULA_ABI_VERSION, per the same header), and the four bindings pass it through. macula-rust
is its own implementation and moves on its own.

Until then the gap is the same shape as the serving one above, and it is written down rather than left to
be discovered: on a macula 18 network an SDK subscriber still hands its app every fact any publisher sent,
and nothing in the app's code says that was the choice.

Where the two halves are tracked. The serving half — a procedure that names no policy is advertised
open — has an issue in every SDK, in its unary and streaming form:
go#60 / #57,
rust#55 / #53,
ts#30 / #27,
py#20 / #18,
dotnet#25 / #24,
php#21 / #19.
The subscriber half has an issue in each SDK as well:
go#61,
rust#56,
py#22,
dotnet#28,
php#23,
ts#32.
They are separate from the twelve above, which are the serving half: none of those mentions a
subscription, and none of these decides who may call. macula-go carries the ABI the other four ride
on, so it goes first; macula-rust, with its own pool, moves independently.

Order for the sources half

  • macula-go — Pool.Subscribe gains the declaration, and the ABI the other four ride on gains its function.
  • macula-py, macula-dotnet, macula-php, macula-ts — pass it through; no pool of their own to change.
  • macula-rust — its own pool, its own schedule.