barrel_server_mcp_live (barrel_server v1.0.1)
View SourceThe live-query bridge: owns every barrel:subscribe_query subscription created over MCP. The bridge process is the subscription owner, so a bridge crash tears all live queries down cleanly; databases with active subscriptions are pinned in the lifecycle manager so the idle sweeper cannot close them mid-query.
Each subscription materializes its rows (keyed by document id) from the snapshot and the add/change/remove deltas. Deltas schedule a debounced notifications/resources/updated for the subscription's barrel://db/{db}/live/{sub} URI (URI only: clients re-read the resource). Sub ids are 16 random bytes (base64url): unguessable URIs are the capability, compensating arity-1 resource reads having no auth context.
The framework never sweeps its subscription state when an MCP session expires, so the bridge sweeps itself: a periodic pass drops subscriptions whose MCP session is gone. Caps bound the damage of a runaway agent: per-session and global subscription counts come from {barrel_server, mcp, #{live => #{...}}} (max_per_session 32, max_global 1024, sweep_interval_ms 60000, debounce_ms 100).
Summary
Functions
The materialized state of a subscription: #{ready, count, rows} (rows id-sorted), plus error after a failed query.
Create a live query owned by the bridge. Returns the sub id and its resource URI.
Test hook: run the session sweep now.
Functions
The materialized state of a subscription: #{ready, count, rows} (rows id-sorted), plus error after a failed query.
-spec subscribe(binary(), binary(), map(), binary() | undefined) -> {ok, binary(), binary()} | {error, term()}.
Create a live query owned by the bridge. Returns the sub id and its resource URI.
-spec sweep() -> {ok, non_neg_integer()}.
Test hook: run the session sweep now.
-spec unsubscribe(binary()) -> ok | {error, not_found}.