Skip to main content

saluki_core/runtime/
mod.rs

1//! Runtime system.
2//!
3//! This module contains the core components of the runtime system, including supervisors and processes. It is directly
4//! inspired by [Erlang/OTP](https://www.erlang.org/docs/28/system/design_principles#supervision-trees).
5//!
6//! To quote the Erlang/OTP documentation:
7//!
8//! > Workers are processes that perform computations and other actual work. Supervisors are processes that monitor
9//! > workers. A supervisor can restart a worker if something goes wrong. The supervision tree is a hierarchical
10//! > arrangement of code into supervisors and workers, which makes it possible to design and program fault-tolerant
11//! > software.
12//!
13//! # Processes
14//!
15//! An asynchronous system is composed of independent units of computation running concurrently, such as a set of tasks
16//! executing on a thread pool. We refer to these as **processes.** In other systems, these might be called _actors_,
17//! _tasks_, _fibers_, _virtual threads_, _goroutines_, or something else. Processes are lightweight and able to be
18//! (generally) created and destroyed cheaply.
19//!
20//! Processes have a few key attributes and invariants:
21//!
22//! - every process is a future that runs as an independent asynchronous task on a Tokio runtime
23//! - every process has a unique numerical identifier and a semi-unique name
24//!
25//! Unlike Erlang processes, Saluki processes do not have an inherent mailbox or message passing capabilities. As well,
26//! processes cannot run by themselves. They must be _supervised_.
27//!
28//! # Supervisors
29//!
30//! Supervisors are themselves processes whose only job is to _supervise_ other processes, also called _workers_. In a
31//! supervisor, workers are added and configured through a common convention that allows defining how the worker is
32//! created (or recreated on failure), how many times it can be restarted, and more. Supervisors themselves can also be
33//! workers, and so nested _supervision trees_ can be constructed.
34//!
35//! Supervisors include a number of configurable settings that allow customizing the behavior of how workers are
36//! managed, which in turn allows building fault-tolerant systems: we can restart workers for transient failures, give
37//! up for permanent failures, and so on.
38//!
39//! # Supervision trees
40//!
41//! As supervisors can be nested, this allows building a tree of supervisors (hence _supervision trees_) where leaf
42//! supervisors manage workers specific to a certain area, and parent supervisors manage the leaf supervisors. For
43//! example, for a server application serving multiple API endpoints, each endpoint might be managed by a separate
44//! supervisor: a worker for accepting connections, a worker for each connection, and so on. Above those supervisors, a
45//! parent supervisor manages each leaf supervisor, and potentially other workers that provide necessary services
46//! utilized by each endpoint, such as logging, metrics, or other infrastructure services.
47//!
48//! As every supervisor can define its own specific restart strategy, and behavior, this allows for more granular
49//! grouping and control over which set of workers must be restarted if a related worker fails, and how those failures
50//! propagate up and down the supervision tree.
51//!
52//! # Examples
53//!
54//! See the `basic_supervisor` example which shows how supervisors and workers are composed together, as well as how
55//! failed workers and supervisors are restarted.
56
57mod process;
58
59mod restart;
60pub use self::restart::{RestartMode, RestartStrategy};
61
62mod supervisor;
63pub use self::supervisor::{ShutdownStrategy, Supervisable, Supervisor, SupervisorError, SupervisorFuture};
64
65mod shutdown;
66pub use self::shutdown::{ProcessShutdown, ShutdownHandle};