macula_content_sharer (macula v13.2.1)

View Source

Shares a pool's content (D27): the node keeps what it shares and serves it itself, and stations only relay. One sharer per pool, ending with the pool.

Serving

Content shared in a realm is served there on the node's own content procedure, a server_stream advertised through the pool like any procedure (macula:advertise_stream/6):

  • <org>/content_v1_<node id hex> when share/4 is given an org the node holds a delegation for;
  • ~<node id hex>/content_v1, the node's own namespace (D25 item 6, revised 2026-09-24), otherwise.

The node id is in the name because a station routes a procedure to one provider (macula-station#8): a shared name would send every fetch to whichever node advertised last. One procedure per realm, fixed by its first share; a later share in the realm under another org is refused. The procedure is withdrawn with the realm's last share.

A realm serves what is shared in it and nothing else: each realm keeps its own store, and its procedure looks up only there.

Announcing

Each root is announced in the DHT under its content id, signed by the pool, naming the realm, the station the node is reachable through now (its first connected link) and the procedure. An announcement lives announce_ttl_ms (an hour by default) and is renewed at half that. Signing and storing it runs in a worker, so sharing and serving never wait on the DHT. Every station_check_ms (30 s) the sharer compares the station it announced with the one it is linked to: it announces everything again when they differ, and otherwise announces what is due, which is every root whose last announcement did not land and every root whose renewal fell while no station was connected. With no station connected the content is kept and served, and announced once a station is. Unsharing withdraws the last announcement under the pool's signature, and one still in flight when it lands.

The mesh

Every call to the mesh goes through the io map start_link/2 takes (status, links, advertise_stream, unadvertise_stream, sign_node_record, put_record, withdraw_node_record), the facade's own functions by default, so a test replaces the mesh without replacing a module.

Summary

Functions

The facade's own functions, the io a sharer uses when not given another.

What this sharer answers in Realm for Want of MCID (macula_content_serve:lookup/3).

Share Bytes in Realm: keep them, serve them, announce their root. Opts may name the content (name) and the org whose delegation serves it (org).

Start a sharer for Pool. Opts holds io entries (see io/0) and announce_ttl_ms, station_check_ms.

Stop sharing the root MCID in Realm. Idempotent.

Functions

handle_call(_, From, S)

handle_cast(Msg, S)

handle_info(Msg, State)

init(_)

io()

-spec io() -> map().

The facade's own functions, the io a sharer uses when not given another.

lookup(Sharer, Realm, Want, MCID)

-spec lookup(pid(), <<_:256>>, macula_content_serve:want(), macula:mcid()) ->
                {ok, macula_content_serve:body()} | not_found.

What this sharer answers in Realm for Want of MCID (macula_content_serve:lookup/3).

share(Sharer, Realm, Bytes, Opts)

-spec share(pid(), <<_:256>>, binary(), map()) -> {ok, macula:mcid()} | {error, term()}.

Share Bytes in Realm: keep them, serve them, announce their root. Opts may name the content (name) and the org whose delegation serves it (org).

start_link(Pool, Opts)

-spec start_link(pid(), map()) -> {ok, pid()} | {error, term()}.

Start a sharer for Pool. Opts holds io entries (see io/0) and announce_ttl_ms, station_check_ms.

unshare(Sharer, Realm, MCID)

-spec unshare(pid(), <<_:256>>, macula:mcid()) -> ok.

Stop sharing the root MCID in Realm. Idempotent.