runtime: extract the supervised host-actor primitive from the venue adapter#441
Conversation
lgahdl
left a comment
There was a problem hiding this comment.
Traced the three riskiest areas (self-locking install, the fuel-refuel/trap-projection generalization, Installed::{Live,Dead} exhaustiveness) and found no correctness bugs — the lock is provably atomic by inspection, trap/refuel messages are byte-identical to the old venue-specific versions, and the one Installed call site is an equality check, not a wildcard. Two things worth a look, both non-blocking:
| } | ||
| adapters.insert(venue, Arc::new(AsyncMutex::new(invoker))); | ||
| Ok(()) | ||
| } |
There was a problem hiding this comment.
Two small things on this one:
- Doc gap: nothing here says
installtakes a synchronousstd::sync::Mutexfor the duration of a plainHashMapinsert, never held across an.await. That's precisely the fact a future reader needs to trust before adding an.awaitinside this critical section, or wondering whether it can deadlock against the asyncActorSlotmutex used elsewhere in this file. Worth a line:// Takes the adapter-map mutex only for the synchronous insert; never held across an await. - Surface: this went from a private builder method (which encoded "install happens before
build()consumesself, then you're frozen") to apubmethod on the shared, cloneableVenueRegistryhandle. Nothing calls it post-boot today, but the type system no longer distinguishes boot-time install from runtime install — a future caller holding a clone can register at any point with no compiler signal. Worthpub(crate)until there's a real post-boot use case, or a boot-only capability/token gating it.
Either is easy to defer; neither blocks this PR.
There was a problem hiding this comment.
Both confirmed still valid at HEAD. install (now videre-host/src/registry.rs:348) is still pub on the cloneable handle, and the mutex-discipline doc line is still absent (the std-mutex-not-across-await comment lives on a different method at line 555, not on install). Tracked in #507.
| Worker, | ||
| /// A provider the host holds behind a serialised actor, named by its | ||
| /// manifest spelling. | ||
| Provider(String), |
There was a problem hiding this comment.
ComponentKind::Provider(String) trades the old enum's compile-time-checked kind set for a runtime-checked open string — a reasonable trade for extensibility, but it means toml::from_str on the manifest now always succeeds regardless of spelling; a typo'd kind = "venu-adapter" only surfaces one layer later, at Supervisor::new/boot (the boot_rejects_an_unregistered_provider_kind test confirms this path is covered and gives a good error naming the registered kinds). Just flagging that manifest-parse success no longer implies a routable kind — worth keeping in mind if any future tooling (a standalone manifest lint command, say) assumes parse success is validation success.
There was a problem hiding this comment.
Still the case at HEAD (manifest/types.rs:226 is still Provider(String)), and by-design: the open provider kind is the extensibility mechanism the extension seam is built on, so a closed enum would defeat it. Validation happens at boot rather than at parse, and boot_rejects_an_unregistered_provider_kind still covers it with an error naming the registered kinds. Leaving as-is; recording the caveat that parse success is not validation success for any future manifest lint-style tooling. (Distinct from #506, which is the closed capability/fault vocabulary that should be enum-typed.)
ca81a60 to
230d417
Compare
0ddfa13 to
ac5e01b
Compare
Closes #377
What
Extracts the generic supervised host-actor primitive (
host::actor::{ActorSlot, SupervisedStore, ActorFault}) out of the venue adapter and generalises provider boot:ProviderKind::installnow takes aProviderInstanceand returnsInstalled { Live | Dead },ComponentKindreplacesModuleKindwith an openProvider(String)spelling resolved against a registered-kinds map (seeded withVenueAdapterKindat boot), andVenueRegistrygained a self-lockinginstallso adapters register through the shared handle instead of the builder.VenueActoris rebuilt on top ofSupervisedStore.Why
AdapterActor/VenueActorspecial-cased the one provider kind the core knew about; the fuel-refuel, trap-projection and call-serialisation machinery only worked for venue adapters. Lifting it intohost::actorand routing manifest kind resolution through a registered-kinds table lets any extension-registered provider reuse the same supervised-store primitive instead of the core baking in a venue-named kind.Testing
Closes #377
AI Assistance
Implemented with AI assistance (Claude Code).