Skip to content

Commit aeb5585

Browse files
committed
enhancement(core): add configurable per-child restart types for supervisors
1 parent a80937c commit aeb5585

3 files changed

Lines changed: 307 additions & 46 deletions

File tree

lib/saluki-core/src/runtime/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ mod dedicated;
6363
pub use self::dedicated::{RuntimeConfiguration, RuntimeMode};
6464

6565
mod restart;
66-
pub use self::restart::{RestartMode, RestartStrategy};
66+
pub use self::restart::{RestartMode, RestartStrategy, RestartType};
6767

6868
mod supervisor;
6969
pub use self::supervisor::{

lib/saluki-core/src/runtime/restart.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,55 @@ impl Default for RestartStrategy {
7474
}
7575
}
7676

77+
/// Restart policy for an individual child process.
78+
///
79+
/// Where [`RestartStrategy`] governs supervisor-wide behavior (which children are restarted together,
80+
/// and how often before the supervisor gives up), the restart policy governs whether an _individual_
81+
/// child is eligible for restart at all, based on how it exited. This mirrors the per-child restart
82+
/// configuration in Erlang/OTP.
83+
///
84+
/// The default is [`Permanent`][Self::Permanent], which preserves the supervisor's historical behavior
85+
/// of always restarting a child that exits.
86+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
87+
pub enum RestartType {
88+
/// The child is always restarted, whether it exits normally or abnormally.
89+
///
90+
/// This suits long-lived processes that are always expected to be running.
91+
#[default]
92+
Permanent,
93+
94+
/// The child is restarted only if it exits abnormally.
95+
///
96+
/// An abnormal exit is an error, panic, or forced abort. A normal exit (the child's future
97+
/// resolves with `Ok(())`) is treated as intentional, and the child is not restarted.
98+
Transient,
99+
100+
/// The child is never restarted, regardless of how it exits.
101+
///
102+
/// This suits short-lived, on-demand children -- for example, one task per network connection --
103+
/// whose termination is a normal part of operation.
104+
///
105+
/// > **Note:** Mixing `Temporary` children into a non-dynamic supervisor that uses
106+
/// > [`RestartMode::OneForAll`] is not yet fully supported: a one-for-all restart triggered by a
107+
/// > sibling will currently restart temporary children as well. Temporary children are intended for
108+
/// > one-for-one supervision (including the dynamic supervisor).
109+
Temporary,
110+
}
111+
112+
impl RestartType {
113+
/// Returns whether a child with this restart policy should be restarted, given how it exited.
114+
///
115+
/// `abnormal` indicates the child exited due to an error, panic, or forced abort, rather than
116+
/// completing normally.
117+
pub(super) fn should_restart(self, abnormal: bool) -> bool {
118+
match self {
119+
Self::Permanent => true,
120+
Self::Transient => abnormal,
121+
Self::Temporary => false,
122+
}
123+
}
124+
}
125+
77126
pub(super) enum RestartAction {
78127
/// Execute a restart with the given mode.
79128
Restart(RestartMode),

0 commit comments

Comments
 (0)