Expand description
Daemon-mode phase 2 (C3): extension notification router.
One subscriber per loaded extension (ProcessExtension::subscribe_notifications),
started ONCE by the host after discovery; forwards widget.* frames
(super::widgets::is_widget_method) to every live session as
SessionEventWire::ExtensionNotification via
crate::host::EngineHost::broadcast_extension_notification.
Routing (phase 3, C2): a frame whose params.session_id is a string is
delivered to THAT session only (dropped with a debug! if it is not
live); a frame without one is daemon-global and goes to every session
(the pre-phase-3 behaviour — docs/extensions/session-id.md §plugin
contract). Delivery is non-blocking: a session whose
command queue is full drops the frame with a warn! — widget upserts are
idempotent last-writer-wins UI state (loop_arms.rs semantics), and
blocking would backpressure the extension’s lossless fan-out and stall
command.invoke / provider.stream subscribers on the same queue.
The inline TUI keeps its own watcher (loop_arms.rs) today; this router
serves actor-hosted sessions (daemon, synaps chat on the actor).
Functions§
- forward_
extension_ notifications - Forward loop for ONE extension. Exits when the extension has been
unloaded from the manager (its channel closed and it is no longer
listed); otherwise resubscribes after [
RESUBSCRIBE_DELAY]. - route_
target params.session_idwhen it is a non-empty string — the frame is session-scoped; otherwise daemon-global (broadcast).- spawn_
notification_ router - Start one forwarding task per loaded extension. Idempotent per call
site by construction — the host calls it once after
extensions_ready(); call it again only after a genuine re-discovery. The returned handle completes once every per-extension task has been spawned (the tasks themselves run for the host’s lifetime and end when their extension is gone and stays gone).