Expand description
Plugin teardown — reversing every contribution a plugin made (PH7.12b.3).
The seam a plugin unload (and, composed with a fresh spawn_*, a
reload) drives. Each contribution surface got a provenance/id-driven
unregister_* in PH7.12b.1; this module aggregates the tokens those
registrations produced (PluginTeardown) and applies each reversal
against the host-owned registries (TeardownRegistries).
Why an explicit driver, not Drop. The registries this touches have
mixed mutability — CommandRegistry / PickerRegistry / ModeRegistry are
&mut-owned by the editor, while ConfigRegistry / KeymapHandle /
EventBus are Arc-shared with interior mutability. A Drop impl would
have to capture all six, forcing every registry behind Arc<Mutex<_>> just
to fit RAII — a strictly weaker foundation. So teardown is an explicit call
the caller makes when it holds the registry set (a &mut Editor context in
Phase 8; the test harness in Phase 7).
Why no reload method. Re-instantiation is just re-invoking the same
spawn_* that produced the plugin, minting a fresh Store with a fresh,
untripped Quarantine. So reload = unload + spawn_*,
composed by the caller (the Phase-8 plugin manager), not a bespoke method.
Completion is absent by design: the host never registers it with plugin
provenance (it goes through the generic builtin-stamped register_generator),
so its teardown is pure channel-drop — dropping the client ends the actor
loop. Decoration (PL8.E) does have a registry — the loader RCU-registers
its producer into the GutterDecorationSourceRegistry — so its teardown
unregisters by producer id, like the picker surface.
Error parsers (CM.6b) have a registry too, but no token: the compilation
parser-factory registry keys entries by the host-issued plugin id, so
reversal is by provenance like the command surface, and there is no
per-contribution Vec on PluginTeardown to populate or to forget.
Structs§
- Plugin
Teardown - The union of teardown tokens a plugin’s contributions produce, aggregated at
spawn time and consumed by
unload. A given plugin populates only the surfaces it exercised; the rest stay empty and their reversal is a no-op. Every field ispubso the spawning caller fills it from the tokens thespawn_*fns already return (Vec<SubscriptionId>,Vec<ModeId>,Vec<String>option names, …). - Teardown
Registries - The host-owned registries a plugin’s contributions live in — the set
PluginTeardown::unloadreverses against. Grouped as a borrow struct sounloadtakes one argument instead of six, and so the caller passes exactly the registries a&mut Editorcontext already holds. All are required: a plugin can contribute to any surface, and passing the whole set is cheaper than threading option-ness through the driver (an unexercised surface’s reversal is already a no-op). - Teardown
Report - Count of what an
unloadactually removed, per surface — for structured logs and test assertions. A field being lower than the bundle’s recorded token count means those entries were already gone (a prior unload, or a crash that never completed registration): expected under idempotent re-unload, not an error.