Expand description
Resource-update subscription registry backing the server-side hooks
for resources/subscribe, resources/unsubscribe, and the two MCP
notifications the server emits after workspace mutations.
The registry keeps, per URI, a Vec<Peer<RoleServer>> of currently
subscribed clients. When a tool call changes workspace state the server
looks up every URI that would be affected (workspace, table list,
per-table schema/sample/csv-sample, per-saved-query result) and calls
SubscriptionRegistry::notify_updated, which spawns a background
task per subscriber to send the notification.
§Tradeoffs in this implementation
rmcp::Peer is Clone but not Eq, and its internal mpsc::Sender
is not exposed for comparison. Rather than reach into private fields
we accept three pragmatic constraints:
- Subscribing twice for the same URI from the same session stores two entries. Subsequent notifications fire twice. The MCP protocol defines no “already subscribed” error, so this is spec-compliant; well-behaved clients subscribe once per URI per session anyway.
- Unsubscribing clears all entries for the given URI. In multi-client
setups this would be surprising, but for the stdio + SSE transports
typically used with
HyperDBeach process serves at most a handful of clients and cross-client URI reuse is rare. - Notify failures (client disconnected) are logged but not pruned. Dead peers accumulate until the MCP session tears the registry down; a future improvement could prune them from the failing detached task, but since notify is a bounded per-tool-call cost and sessions are short-lived this hasn’t mattered in practice.
Structs§
- Subscription
Registry - Per-URI registry of subscribed peers with broadcast helpers.
Functions§
- uris_
for_ table_ change - The full set of resource URIs that are affected when a specific table
is written to. Used by mutation-side helpers in
server.rsto fire targeted updates without sprinkling URI strings across every tool. - uris_
for_ workspace_ change - The URIs affected by a workspace-wide change that doesn’t name any
single table (e.g. watcher activity touching multiple files, or a
saved-query list mutation).
hyper://tablesreflects the updated catalog,hyper://readmecontains the summary that cross-references everything else.