Signals
Dusk processes can be signaled, just like Unix-like processes. The main usage of signals is telling processes when it is time to stop.
The Signal type
Dusk maps the wire signal number to a small enum:
Rust
#[non_exhaustive]
pub enum Signal {
Sweep, // signal number 7
Reap, // signal number 8
Terminate, // signal number 15
Rerun(Rc<ProgramArgs>), // this pid was asked for a second time
Unknown(u64), // any other number, carried through unchanged
}
Signal is #[non_exhaustive], so a match on it needs a wildcard arm. Dusk can
then add a signal without breaking programs that were written before it existed.
Sweep(7) is handled by the node and never reaches a process. It takes a suspended process - one that was created and never run - out of the namespace, and does nothing to a process that has run.Reap(8) is handled by the node and never reaches a process. It reaps a zombie process, logging its exit result and taking it out of the namespace, and does nothing to a non-zombie process.Terminate(15) is the request to exit; a well-behaved process returns frommainwhen it sees it. It's the default sent bykill.Rerun(args)arrives when someone builds a process at a pid this process already holds. The running process is the answer, soargsis the second set of arguments, for the rare program that wants to look at them. Ignoring it is the right default.Unknown(n)carries any other number through as-is, so a program can give additional signal numbers its own meaning.
Receiving signals
main is handed a SignalReceiver (a DynamicReceiver<Signal>). The usual shape
is a loop that awaits the next signal and exits on Terminate:
Rust
loop {
match signal_receiver.receive().await {
Signal::Terminate => return Ok(()),
Signal::Unknown(_) => { /* program-defined */ }
_ => {}
}
}
A process that also does ongoing work selects that work against the receiver.
See Processes › Signals.