task_supervisor/supervisor/
builder.rs1use std::{collections::HashMap, time::Duration};
2
3use tokio::sync::mpsc;
4
5use crate::{
6 task::{CloneableSupervisedTask, TaskHandle},
7 Supervisor,
8};
9
10pub struct SupervisorBuilder {
15 tasks: HashMap<String, TaskHandle>,
16 health_check_interval: Duration,
17 max_restart_attempts: Option<u32>,
18 base_restart_delay: Duration,
19 max_backoff_exponent: u32,
20 task_stable_after_delay: Duration,
21 max_dead_tasks_percentage_threshold: Option<f64>,
22}
23
24impl SupervisorBuilder {
25 pub fn new() -> Self {
27 Self {
28 tasks: HashMap::new(),
29 health_check_interval: Duration::from_millis(200),
30 max_restart_attempts: Some(5),
31 base_restart_delay: Duration::from_secs(1),
32 max_backoff_exponent: 5,
33 task_stable_after_delay: Duration::from_secs(80),
34 max_dead_tasks_percentage_threshold: None,
35 }
36 }
37
38 pub fn with_task(mut self, name: &str, task: impl CloneableSupervisedTask) -> Self {
40 let handle = TaskHandle::from_task(
41 task,
42 self.max_restart_attempts,
43 self.base_restart_delay,
44 self.max_backoff_exponent,
45 );
46 self.tasks.insert(name.into(), handle);
47 self
48 }
49
50 pub fn with_max_backoff_exponent(mut self, exponent: u32) -> Self {
55 self.max_backoff_exponent = exponent;
56 self
57 }
58
59 pub fn with_health_check_interval(mut self, interval: Duration) -> Self {
61 self.health_check_interval = interval;
62 self
63 }
64
65 pub fn with_max_restart_attempts(mut self, attempts: u32) -> Self {
67 self.max_restart_attempts = Some(attempts);
68 self
69 }
70
71 pub fn with_unlimited_restarts(mut self) -> Self {
73 self.max_restart_attempts = None;
74 self
75 }
76
77 pub fn with_base_restart_delay(mut self, delay: Duration) -> Self {
79 self.base_restart_delay = delay;
80 self
81 }
82
83 pub fn with_task_being_stable_after(mut self, delay: Duration) -> Self {
86 self.task_stable_after_delay = delay;
87 self
88 }
89
90 pub fn with_dead_tasks_threshold(mut self, threshold_percentage: Option<f64>) -> Self {
96 self.max_dead_tasks_percentage_threshold = threshold_percentage.map(|t| t.clamp(0.0, 1.0));
97 self
98 }
99
100 pub fn build(self) -> Supervisor {
102 let (internal_tx, internal_rx) = mpsc::unbounded_channel();
103 let (user_tx, user_rx) = mpsc::unbounded_channel();
104 Supervisor {
105 tasks: self.tasks,
106 health_check_interval: self.health_check_interval,
107 base_restart_delay: self.base_restart_delay,
108 max_restart_attempts: self.max_restart_attempts,
109 max_backoff_exponent: self.max_backoff_exponent,
110 task_is_stable_after: self.task_stable_after_delay,
111 max_dead_tasks_percentage_threshold: self.max_dead_tasks_percentage_threshold,
112 internal_tx,
113 internal_rx,
114 external_tx: user_tx,
115 external_rx: user_rx,
116 }
117 }
118}
119
120impl Default for SupervisorBuilder {
121 fn default() -> Self {
122 Self::new()
123 }
124}