52 lines
2.3 KiB
Markdown
52 lines
2.3 KiB
Markdown
# 0001: Worker-local execution with instruction slices
|
|
|
|
Status: Accepted for the Phase 1 prototype
|
|
|
|
## Decision
|
|
|
|
Share immutable Rune 0.14.2 compiled units and native contexts, but create an
|
|
independent VM stack for each invocation. Keep invocations and Rune values on
|
|
one worker. No actor-specific state lives in a shared context or native closure.
|
|
|
|
Use `VmExecution::async_step` inside an owned, pinned invocation future.
|
|
Preserve that future across awaits; cancelling an individual `async_step`
|
|
future and creating another could lose the pending await.
|
|
|
|
Yield to the host after each completed step. `Invocation::poll_slice` executes
|
|
at most its configured number of step polls and returns one of:
|
|
|
|
- `Completed`: the converted result is ready.
|
|
- `Awaiting`: a native async operation is pending.
|
|
- `BudgetExhausted`: the host slice is consumed; the invocation is resumable.
|
|
- `Failed`: execution or result conversion failed.
|
|
|
|
This boundary does not inspect Rune error text. The older Phase 0 budget probe
|
|
still checks the pinned budget diagnostic as a compatibility experiment.
|
|
|
|
The single-worker runtime visits each runnable actor once per tick. Each actor
|
|
has at most one reserved message and one invocation. Awaiting actors are
|
|
repolled after a wake, not continually busy-polled.
|
|
|
|
## Alternatives
|
|
|
|
Rune's aggregate instruction budget is cheaper than one-step scheduling but
|
|
its typed exhaustion discriminator is private in 0.14.2. Parsing its display
|
|
text is not suitable for runtime policy. An upstream typed slicing API could
|
|
replace stepping later, after measurement.
|
|
|
|
Moving active executions between workers adds thread-safety obligations not
|
|
needed by this prototype. No execution-adapter trait or shared core crate is
|
|
introduced without a concrete consumer.
|
|
|
|
## Consequences
|
|
|
|
This is bounded cooperative VM scheduling, not wall-clock preemption.
|
|
One Rune instruction can call native code; blocking callbacks or expensive
|
|
native operations can still monopolize a worker. Native callbacks must be
|
|
reviewed for nonblocking behavior and cancellation.
|
|
|
|
Tests establish fairness for pure Rune runaway loops, budgets before and after
|
|
awaiting, wake-driven resumption, and local-future cleanup on cancellation.
|
|
They do not establish safe interruption of arbitrary external I/O, heap limits,
|
|
source debugging, or fairness across real worker threads.
|