Skip to main content

Module fan_in

Module fan_in 

Source
Expand description

Per-actor LspDocumentChanged -> ActorCmd::RecordEdit fan-in.

Subscribes one typed channel per actor to the editor’s event bus (M.5.5: EventBus::subscribe_typed::<LspDocumentChanged>). On every event whose path resolves to a URI the actor cares about, it forwards one RecordEdit actor command per applied edit.

The publisher (App’s publish_document_changed) only fires LspDocumentChanged when lsp-mode is active for the edited buffer, so the gate happens at the publish site – fan_in never sees edits the user gated off via :lsp-mode. The generic Event::DocumentChanged keeps firing for non-LSP subscribers regardless.

§Why per-actor and not one shared dispatcher

Each actor owns its own DocSync mirror; the only writer to that mirror is the actor’s own task. Routing edits straight into the actor’s mailbox makes the edit path lock-free end-to-end (publish on the UI thread is a single mutex grab on the bus inner; the rest is fully async). A central dispatcher would re-introduce a shared lock on the attachments map and serialise every edit through it – the exact contention pattern this refactor exists to remove.

§Lifecycle

  • The supervisor calls spawn right after a new actor is running. The returned [SubscriptionId] is stored next to the actor so it can be unsubscribed at shutdown.
  • The fan-in task exits when the bus drops the channel (supervisor called unsubscribe, dropping the sender) or when the actor’s record_edit returns LspError::ActorGone (the supervisor dropped the handle).

§Filtering by attached URIs

The fan-in does not know which URIs are attached to which actor. Instead it forwards every LspDocumentChanged whose path is Some(_) to its actor; the actor’s DocSync warns + skips on URIs it doesn’t track. This trades a small amount of per-event work (one Uri build + one mpsc send) against keeping the supervisor’s attachment map out of the hot path.

Functions§

spawn
Subscribe handle to every LspDocumentChanged event on bus (M.5.5; previously Event::DocumentChanged) and spawn a tokio task that forwards them as RecordEdit actor commands. Returns the subscription id; the supervisor must hand this to [EventBus::unsubscribe] when the actor is dropped to keep the bus’s bucket from accumulating dead entries.