Repository navigation
nvx-rs: make the host module's dependency graph acyclic #897
Description
Parent: #896. Needs: nothing. Unblocks: #898, #899.
Goal. Make the production dependency graph between nvx::host's direct children acyclic by moving three misplaced items, with no behavioral or public API change, and add a guard that keeps it acyclic.
Today (dev 6af32ba0): the references between host's children, as #896 defines them, form one strongly connected component of 8 children: artifacts, filesystem, launch, platform, process, sandbox, store and supervisor. Three back-edges close it:
platform→supervisor.Inherited, with itsBorrowedalias and its impls, is defined innvx-rs/src/host/supervisor/child.rs:30-113, andplatform/linux.rs:12,platform/windows.rs:64andplatform/other.rs:8importcrate::host::supervisor::Inherited.store→supervisor. The rest ofsupervisor::child,VmmCommand,spawnandLaunched(child.rs:115-405), imports onlyplatform,processandprotocol(child.rs:24-28). Butstore/mod.rs:242importssuper::supervisor::Launched, whilesupervisorimportsstore(supervisor/mod.rs:109-112).artifacts→sandbox.require_artifact(pub(crate),sandbox/mod.rs:154-158) and the privaterequire_existing(160-170) andrequire_pure_file(464-471) live insandbox, andartifacts.rs:42importsrequire_artifactforrequired(artifacts.rs:871-876), whilesandbox/distro.rs:49importsartifacts::DISTRO_MANIFEST_SUFFIX.
Changes:
- Move
InheritedandBorrowedinto a new crate-visible module,host::platform::inherit.Inheritedstayspub, and is re-exported only asnvx::host::supervisor::Inherited. - Move
supervisor/child.rsto a privatehost::spawnmodule, withgit mv.supervisorre-exportsLaunched,VmmCommandandspawn(supervisor/mod.rs:106today), andstoreimportssuper::spawn::Launched. The link[launch](super::launch)(child.rs:166) gets acrate::path (nvx-rs: break the host module into finer-grained modules #896, invariant 6), as does the link tospawninInherited's documentation (child.rs:45). - Move
require_artifact,require_existingandrequire_pure_fileintohost::artifacts, aspub(crate). The publicsandbox::require_file(sandbox/mod.rs:146-152) stays, and callsartifacts::require_existing. Their other users import them fromartifacts:cli/run.rs:41,cli/sandbox/mod.rs:48-52andsandbox/plan.rs:114-117. - Guard:
nvx-rs/tests/host_modules.rs, a std-only integration test that reads the sources undersrc/hostand builds the production graph between host's children as nvx-rs: break the host module into finer-grained modules #896 defines it. It resolvescrate::,super::andself::paths inusetrees and expressions, and the crate-root re-exports, and skips comments andcfg(test)code, so the links ofchild.rs:165and216tostore::Launch::record_processare not edges. It fails with a list of each cycle, with one example reference per edge. It runs in check-nvx-rs's existingcargo teststeps (.github/actions/check-nvx-rs/action.yml:57-69), with no new dependency and no workflow change. It must fail on today'sdevand pass after the three moves.
Resulting order of host's children, lowest first, from the graph of 6af32ba0 with the three moves applied:
| Layer | Children |
|---|---|
| 0 | sys, python, network, seal, report |
| 1 | platform |
| 2 | filesystem, nvxs, process |
| 3 | session, spawn |
| 4 | store |
| 5 | artifacts |
| 6 | launch |
| 7 | supervisor |
| 8 | instance, sandbox |
| 9 | cli |
The template stack (#896). At the head of #888 (a2d5ddf9), the new host::template joins the cycle, which grows to 12 children. With the three moves, two of its edges still close one: store → template (template::Lease, from #886) and sandbox → template (template::BlockGeometry, in sandbox/{mod,distro,scratch}.rs, from #888). Without those two, the graph is acyclic, with template beside cli at the top. Whichever lands second, this issue or the stack, resolves them, for example by moving the items that store and sandbox take below them.
Evidence from a prototype on dev 8522cc4e:
- 14 files, +151/-136.
- The public API surface from rustdoc JSON is identical: 2,278 entries on Windows and 3,095 on Linux, with 0 differences.
- 706 library tests pass on Windows, and the Windows test list is unchanged.
- On Linux, the four Linux-only tests of
supervisor::child(child.rs:407-554today) becomehost::spawn::tests::*. No coverage family or bundling filter is affected.
Tests: the guard; the public API diff (#896, invariant 1); and cargo test -- --list on Linux and Windows, which changes only by the rename of those four Linux tests.
Acceptance. The graph between host's children is acyclic in production code. The guard is green on the PR and demonstrably red on today's dev. The public API diff is zero on Linux and Windows. CI is green.
Activity