Skip to content

Commit 197f832

Browse files
refactor: deduplicate ChildSpec and RestartType code
- Extract ChildSpec::new_with_type() helper to remove duplication between worker() and supervisor() constructors - Add RestartType::should_restart() method to centralize restart decision logic used in both Supervisor and DynamicSupervisor 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent e12bca7 commit 197f832

File tree

1 file changed

+34
-27
lines changed

1 file changed

+34
-27
lines changed

concurrency/src/supervisor.rs

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ pub enum RestartType {
5757
Temporary,
5858
}
5959

60+
impl RestartType {
61+
/// Determine if a child should be restarted based on exit reason.
62+
pub fn should_restart(self, reason: &ExitReason) -> bool {
63+
match self {
64+
RestartType::Permanent => true,
65+
RestartType::Transient => !reason.is_normal(),
66+
RestartType::Temporary => false,
67+
}
68+
}
69+
}
70+
6071
/// Child shutdown behavior.
6172
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6273
pub enum Shutdown {
@@ -181,6 +192,21 @@ pub struct ChildSpec {
181192
}
182193

183194
impl ChildSpec {
195+
/// Create a new child specification with the given type.
196+
fn new_with_type<F, H>(id: impl Into<String>, start: F, child_type: ChildType) -> Self
197+
where
198+
F: Fn() -> H + Send + Sync + 'static,
199+
H: ChildHandle + 'static,
200+
{
201+
Self {
202+
id: id.into(),
203+
start: Arc::new(move || Box::new(start()) as BoxedChildHandle),
204+
restart: RestartType::default(),
205+
shutdown: Shutdown::default(),
206+
child_type,
207+
}
208+
}
209+
184210
/// Create a new child specification for a worker.
185211
///
186212
/// # Arguments
@@ -198,13 +224,7 @@ impl ChildSpec {
198224
F: Fn() -> H + Send + Sync + 'static,
199225
H: ChildHandle + 'static,
200226
{
201-
Self {
202-
id: id.into(),
203-
start: Arc::new(move || Box::new(start()) as BoxedChildHandle),
204-
restart: RestartType::default(),
205-
shutdown: Shutdown::default(),
206-
child_type: ChildType::Worker,
207-
}
227+
Self::new_with_type(id, start, ChildType::Worker)
208228
}
209229

210230
/// Create a new child specification for a supervisor (nested supervision).
@@ -218,13 +238,7 @@ impl ChildSpec {
218238
F: Fn() -> H + Send + Sync + 'static,
219239
H: ChildHandle + 'static,
220240
{
221-
Self {
222-
id: id.into(),
223-
start: Arc::new(move || Box::new(start()) as BoxedChildHandle),
224-
restart: RestartType::default(),
225-
shutdown: Shutdown::default(),
226-
child_type: ChildType::Supervisor,
227-
}
241+
Self::new_with_type(id, start, ChildType::Supervisor)
228242
}
229243

230244
/// Get the ID of this child spec.
@@ -698,14 +712,11 @@ impl SupervisorState {
698712
}
699713

700714
// Determine if we should restart based on restart type
701-
let should_restart = match self.children.get(&child_id) {
702-
Some(info) => match info.spec.restart {
703-
RestartType::Permanent => true,
704-
RestartType::Transient => !reason.is_normal(),
705-
RestartType::Temporary => false,
706-
},
707-
None => false,
708-
};
715+
let should_restart = self
716+
.children
717+
.get(&child_id)
718+
.map(|info| info.spec.restart.should_restart(reason))
719+
.unwrap_or(false);
709720

710721
if !should_restart {
711722
return Ok(Vec::new());
@@ -1222,11 +1233,7 @@ impl DynamicSupervisorState {
12221233
};
12231234

12241235
// Determine if we should restart based on restart type
1225-
let should_restart = match info.spec.restart {
1226-
RestartType::Permanent => true,
1227-
RestartType::Transient => !reason.is_normal(),
1228-
RestartType::Temporary => false,
1229-
};
1236+
let should_restart = info.spec.restart.should_restart(reason);
12301237

12311238
if !should_restart {
12321239
return Ok(());

0 commit comments

Comments
 (0)