feat(runtime): type-state RuntimeBuilder, LaunchRuntime and RuntimeHandle#193
Open
mfw78 wants to merge 2 commits into
Open
feat(runtime): type-state RuntimeBuilder, LaunchRuntime and RuntimeHandle#193mfw78 wants to merge 2 commits into
mfw78 wants to merge 2 commits into
Conversation
…ndle Add a type-state RuntimeBuilder that accumulates the config, the RuntimeTypes lattice, extensions, the component builders and the add-on set, then opens the backends and hands off to a LaunchRuntime launcher. LaunchRuntime::launch runs the one imperative sequence over a LaunchContext (executor, data dir, config): install add-ons, build the engine and linker, boot the supervisor, open subscriptions through the task executor, spawn the event loop, and return a RuntimeHandle owning the event-loop task handle, a shutdown trigger and the add-on handles. run_from_config becomes a one-liner over the builder; bootstrap::run forwards to the same launcher from pre-built backends so the embed example is unchanged. Behaviour is unchanged: the supervisor E2E and event-loop tests still pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #92.
Introduces a type-state
RuntimeBuilder, aLaunchRuntimetrait, and aRuntimeHandle, replacing the ad hoc bootstrap sequence with a chain where a missing step is a compile error rather than a runtime surprise.This is part of the epic #79 train and merges in stack order.
Changes
crates/nexum-runtime/src/builder.rsis new and holds the architectural centrepiece:LaunchContextcarries the ambient launch inputs (executor, data directory, config),LaunchRuntime::launchis implemented once forAssembledRuntimeand holds the single copy of the imperative launch sequence (install add-ons, build engine and linker, boot the supervisor, open subscriptions, spawn the event loop), andRuntimeHandlewraps the spawned task handle together with a graceful shutdown trigger.The type-state chain runs
RuntimeBuilder::new(config)throughwith_types, then the optionalwith_extensionsandwith_module_source, thenwith_components, thenwith_add_ons, and finallylaunch. Each stage is its own struct, so a caller cannot skip a required step and still compile.crates/nexum-runtime/src/bootstrap.rsis rewritten to forward pre-built backends intoAssembledRuntimeandLaunchContext, then calllaunch().await?.wait().await. Its signature and behaviour are unchanged, soexamples/embed.rsneeded no changes.crates/nexum-cli/src/launch.rsnow expressesrun_from_configas a single expression over the builder chain.The event loop is spawned through the executor rather than awaited inline, so the handle can hold a genuine task handle alongside the shutdown trigger. The OS-signal future is selected against the programmatic oneshot trigger inside the spawned task, so CLI blocking behaviour is unchanged.
wait()treats a missing join reason (panic or abort) as an error, matching the prior inline-await panic propagation, and there is noDropimpl: dropping the handle fires the trigger through the oneshot sender's drop, which is documented on the type.Test plan
cargo fmt --all --checkcargo clippy --workspace --all-targets --all-features -- -D warningscargo test --workspace --all-features, including the wasm-backed end-to-end fixtures (cow_boot,e2e_twap_monitor_block_dispatch,e2e_ethflow_watcher_log_dispatch,e2e_stop_loss_block_dispatch) built and run rather than skippedNotes for reviewer
The issue names
with_components(CB)as taking a builder, butbootstrap::run,embed, and the existing tests all hold pre-builtComponents. Rather than duplicate the launch sequence for both shapes,AssembledRuntimecarries pre-built backends and owns the imperative body, while the type-state builder'slaunchbuilds components first throughComponentsBuilderand then constructs anAssembledRuntimeinternally.with_extensionsandwith_module_sourceare additions beyond the three methods named in the issue:run_from_configneeds extensions and the CLI's positional wasm or manifest override, and the issue's method list was illustrative rather than exhaustive.Two follow-ups are deliberately left out of scope.
examples/embed.rsstill callsbootstrap::rundirectly and retainscomponents.logsmanually; moving it to the builder would needRuntimeHandleto expose a log read-handle, which is a small API addition better done separately. Once external callers move to the builder orLaunchRuntimedirectly,bootstrap::runcould be deleted in favour of one launch surface, since it is now a thin shim overAssembledRuntimeandLaunchRuntime.AI Assistance: Claude Code (Opus 4.8 implementation and adversarial review, Sonnet 5 PR authoring) used for the full change.