Expand description
Processes and supervision — OTP’s structure over blue’s scheduler.
This is the layer that makes let it crash a strategy rather than a slogan, and it is only buildable because two things landed underneath it:
- bounded, catchable failure — a runaway returns a typed
VmError::BudgetExhaustedinstead of aborting the OS process, so a supervisor has something to catch; - preemption —
Vm::stepparks at a quantum with the frame stack intact, so one process cannot starve its siblings.
Both are the same reduction counter, read as a total ceiling and as a per-slice ceiling.
§The isolation this does and does not provide
Stated first, because overstating it would be the easy mistake. Each
process gets its own Vm — its own value stack, frame stack,
handlers and local cells. That is real isolation of control state: one
process’s crash cannot corrupt another’s stack, and a runaway is
contained.
Each process also owns its own Interpreter, so it owns its own
globals. A definition or a mutation in one process is invisible to its
siblings, and a restart discards them — which is what makes let-it-crash a
guarantee rather than a hope: the restarted process cannot inherit the
corrupted state that killed it.
Messages are deep-copied on send (mailbox::deep_copy). Value is
Arc-based, so a naive send would share structure between processes and
quietly reintroduce the coupling the separate interpreters removed.
The cost is stated rather than hidden: one interpreter per process means
the primitives and the Lisp stdlib are installed per process, and
Supervisor::interpreters_built counts it. That is the same trade the
test framework makes for per-test isolation, and for the same reason —
shared state makes order significant.
This is sumika at the environment level. It is not a per-process
GC heap: allocation still goes through Rust’s allocator and reclamation is
still Arc refcounting, so there is no independent per-process collection
pause. theory/BLUE.md §V records that as the remaining distance.
§Strategy names follow caixa, deliberately
caixa-core’s Supervisor kind already carries estrategia with
OneForOne / OneForAll / RestForOne / SimpleOneForOne, plus
max-restarts and a restart window. The org rule is one vocabulary per
concept, so Strategy uses those names rather than inventing a second
set.
Re-exports§
pub use mailbox::deep_copy;pub use mailbox::install_process_primitives;pub use mailbox::System;
Modules§
- mailbox
- Mailboxes,
send, andreceive.
Structs§
- Pid
- A process identifier.
- Proc
- One process: a program, its own VM, and its own interpreter.
- Supervisor
Enums§
- Event
- A record of what the supervisor did, so a caller can assert on behaviour rather than infer it from final state.
- Exit
Reason - Why a process stopped.
- Proc
State - No
PartialEq:tatara_lisp_eval::Valuedoes not implement it, and wrapping it in a comparable shim here would invent an equality the runtime does not define. Callers ask the questions they actually mean —ProcState::is_runnable,ProcState::done_int. - Strategy
- Restart strategy. Names follow
caixa-core’sestrategia.
Traits§
- Readiness
- What the scheduler needs to know about the host, and nothing more.
Functions§
- forking
- A supervisor over an ordered set of children.
A
Supervisor::spawnfactory that forks one prototype instead of rebuilding the standard library per process and per restart.