Skip to content

nvx-rs: a shared credit and stdio engine for executions #623

Closed

Description

Parent: #535. Phase: A5. Needs A1-guest's exec, status and cgroup interfaces. Delivers: #537's engine.

Goal. One framing-free credit and stdio engine gives bounded in-flight memory with no total output cap. Independently framed adapters drive it, and so will NVXC v2. NVX's cutover to v2, its admission queue, the guest build identity and #581's decoder moved to #816.

Today (dev ff95973):

Scope:

  1. One shared engine: a std-only module (for example nvx::exec) that builds without default features or Tokio. A1's guest driver supplies the Linux process and descriptor mechanics; hosts may be synchronous or asynchronous.
    • Types: execution and generation key, stream, credit pool, byte or frame limits, maximum chunk, termination cause, caller-reaped status, settlement result and terminal outcome.
    • Inputs: credit grant, data, EOF, consumed or written acknowledgements, launch result, observed exit, cancel, drop, disconnect, reset, a monotonic deadline tick and the settlement result.
    • Outputs: started; bounded read and write allowances; output, data, EOF and credit; termination and settlement requests; exactly one terminal outcome; and whether the execution is reusable or fenced.
    • Driving: non-blocking transitions, bounded action retrieval and the next deadline. No wire types, global admission or hidden reaper.
    • Credit pools: NVXC uses one bounded window per stream. Another adapter may charge frames and share one pool between stdout and stderr. The engine alone does the credit arithmetic: initial grants, partial consumption, over-credit refusal, late messages and an aggregate memory bound.
  2. EOF, order and completion:
    • Stdin EOF follows every accepted input byte and doesn't close the control direction. A workload that closes stdin early never leaves the producer waiting.
    • Each stream keeps its order. A normal EXIT follows both streams' final data and EOF; there is no order across streams.
    • Cancel, timeout, reset, drop, disconnect and Stop progress whatever the streams are doing. Pending output drains for a bounded grace, then is discarded with a truncation flag in the terminal record. Normal completion is always lossless.
    • The logical outcome, delivery completion and settlement are separate. Admission reopens only after the descendants and inherited pipe writers have settled. A failed cleanup fences the execution. A caller may request forced teardown of the verified VM; the CLI's Stop never does. Leader exit, a process-group signal or an outer ACK never counts as settlement.

Moved to #816: #581's shared EXEC body decoder (formerly scope 1); NVXC v2, Ready and its validation, and the CLI's streaming and the other callers (scopes 4, 5 and 7, #821); the guest build ID and packaging (scopes 5 and 8, #820); the CLI's admission (scope 6, #819); and the bundled re-pin (#624).

Not in scope: #513 (fixed by merged PR #585), restore, TTY and resizing, arbitrary signals, exec concurrency in NVX's adapter, other adapters' admission policy, Python-parity helpers, and a redesign of aci_edge_sandboxes.

Acceptance:

  • Deterministic engine tests cover window edges, tiny and maximal frames, invalid grants, partial consumption, EOF, early stdin close, late or stale messages and terminal races.
  • A slow or blocked stdin, stdout or stderr never stops timers, cancel, reset or Stop, including under transport backpressure and an exhausted outer window.
  • Normal streams are byte-exact beyond 1 MiB, stdin exceeds one window, and memory stays bounded without collecting the whole test stream.
  • Descendant, reparenting, setsid, inherited-pipe and cleanup-failure tests prove settlement before readmission; unrelated children and other adapters' concurrent executions are untouched.
  • The test adapter uses its own framing and a frame-counted shared output pool, and runs several executions at once without enabling concurrency in NVX's adapter.
  • The engine's cases of consumer-contract scenario C2 pass through the test adapter; NVX's adapter covers C1 and C2 with nvx-rs: move NVX's adapter to NVXC v2 on the shared engine, with a validated Ready #821.

PR stack:

  1. The shared engine on A1's driver seam, with stdio and control that stay live under blocked streams, and the test adapter's tests (nvx-rs: add the shared execution engine and its guest binding #748, tests: run executions in the runtime adapter through the shared engine #784).

The earlier PRs 1 and 3–5 moved to #816: #581, #819, #820 and #821.

Carries over: #537's engine, reusing #358 and #359's regression tests. #581 and #537's NVX stdin and output-cap part moved to #816.


Meta A: #535. Phases: A1-guest #619, A1-host #620, A3 #621, A4 #622, A5 #623. NVX's binaries and tools, and the final acceptance: #816.

Activity

  1. changed the title [-]nvx-rs: exec v2 with credit-based streaming[/-] [+]nvx-rs: a shared credit and stdio engine for executions[/+] on Oct 23, 2026
  2. esaurez commented on Oct 23, 2026

    @esaurez
    ContributorAuthor

    The shared engine merged in #748, and the test adapter runs executions through it (#784). #581, NVXC v2, the CLI's admission and the guest build identity moved to #816.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions