pub struct Supervisor<H> {
pub events: Vec<Event>,
pub interpreters_built: usize,
/* private fields */
}Fields§
§events: Vec<Event>§interpreters_built: usizeInterpreters constructed — one per spawn plus one per restart. Reported so the cost of per-process isolation is visible rather than hidden.
Implementations§
Source§impl<H: 'static> Supervisor<H>
impl<H: 'static> Supervisor<H>
pub fn new(strategy: Strategy, max_restarts: usize) -> Self
Sourcepub fn spawn<F>(&mut self, chunk: Arc<Chunk>, budget: Budget, build: F) -> Pid
pub fn spawn<F>(&mut self, chunk: Arc<Chunk>, budget: Budget, build: F) -> Pid
Add a child. Order matters for Strategy::RestForOne.
build constructs this process’s interpreter, and is called again on
every restart. It is a factory rather than a value because a restart
must produce a fresh environment: handing over one pre-built
interpreter would mean a crashed process restarts into the globals that
killed it.
Prefer forking to a closure that builds from scratch. A factory
calling interpreter_hostless() evaluates the whole Lisp standard
library on every spawn and every restart — ~945µs each, for an
identical result — and a supervision tree under a crash loop pays it
repeatedly. forking gives the same guarantee (a restart gets a clean
private frame, and cannot write the prototype’s globals) for ~29µs.
pub fn state_of(&self, pid: Pid) -> Option<&ProcState>
Sourcepub fn proc_binds(&self, pid: Pid, name: &str) -> Option<bool>
pub fn proc_binds(&self, pid: Pid, name: &str) -> Option<bool>
Does this process’s own environment bind name?
Exposed because “a restart discards the environment” is otherwise untestable: a counter proves a rebuild was requested, not that the old bindings are gone. Also useful when debugging a supervision tree.
pub fn restarts_of(&self, pid: Pid) -> Option<usize>
Sourcepub fn has_work(&self, host: &H) -> boolwhere
H: Readiness,
pub fn has_work(&self, host: &H) -> boolwhere
H: Readiness,
Is anything still runnable? Is there anything to run right now?
A blocked process counts only if the host says it is ready. A blocked
process with nothing pending is not work — it is a deadlock, and
Supervisor::round reports it.
Sourcepub fn deadlocked(&self, host: &H) -> Vec<Pid>where
H: Readiness,
pub fn deadlocked(&self, host: &H) -> Vec<Pid>where
H: Readiness,
Processes parked with nothing to wake them.
Sourcepub fn round(&mut self, host: &mut H)where
H: Readiness,
pub fn round(&mut self, host: &mut H)where
H: Readiness,
Run one scheduling round: give every runnable process one quantum, then apply the restart strategy to anything that exited abnormally.
Round-robin, so a long-running child cannot starve a short one — that is preemption’s contribution, and it holds without any child cooperating.