Skip to main content

Module teardown

Module teardown 

Source
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§

PluginTeardown
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 is pub so the spawning caller fills it from the tokens the spawn_* fns already return (Vec<SubscriptionId>, Vec<ModeId>, Vec<String> option names, …).
TeardownRegistries
The host-owned registries a plugin’s contributions live in — the set PluginTeardown::unload reverses against. Grouped as a borrow struct so unload takes one argument instead of six, and so the caller passes exactly the registries a &mut Editor context 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).
TeardownReport
Count of what an unload actually 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.