use std::{collections::HashMap, sync::Arc, time::Duration};
use crate::{
supervisor::{Config, Supervisor},
task::{Slot, SupervisedTask},
SupervisorHandle,
};
pub struct SupervisorBuilder {
tasks: HashMap<Arc<str>, Slot>,
config: Config,
}
impl SupervisorBuilder {
pub fn new() -> Self {
Self {
tasks: HashMap::new(),
config: Config {
max_restarts: Some(5),
restart_window: Duration::from_secs(60),
base_restart_delay: Duration::from_secs(1),
max_restart_delay: Duration::from_secs(30),
restart_jitter: 0.1,
dead_tasks_threshold: None,
stop_timeout: Duration::from_secs(5),
},
}
}
pub fn with_task(mut self, name: &str, task: impl SupervisedTask) -> Self {
let name: Arc<str> = Arc::from(name);
self.tasks
.insert(Arc::clone(&name), Slot::new(name, Box::new(task)));
self
}
pub fn with_restart_limit(mut self, max_restarts: u32, window: Duration) -> Self {
self.config.max_restarts = Some(max_restarts);
self.config.restart_window = window;
self
}
pub fn with_unlimited_restarts(mut self) -> Self {
self.config.max_restarts = None;
self
}
pub fn with_base_restart_delay(mut self, delay: Duration) -> Self {
self.config.base_restart_delay = delay;
self
}
pub fn with_max_restart_delay(mut self, delay: Duration) -> Self {
self.config.max_restart_delay = delay;
self
}
pub fn with_restart_jitter(mut self, fraction: f64) -> Self {
self.config.restart_jitter = fraction.clamp(0.0, 1.0);
self
}
pub fn with_dead_tasks_threshold(mut self, fraction: f64) -> Self {
self.config.dead_tasks_threshold = Some(fraction.clamp(0.0, 1.0));
self
}
pub fn with_stop_timeout(mut self, timeout: Duration) -> Self {
self.config.stop_timeout = timeout;
self
}
pub fn spawn(self) -> SupervisorHandle {
Supervisor::spawn(self.tasks, self.config)
}
}
impl Default for SupervisorBuilder {
fn default() -> Self {
Self::new()
}
}