use std::time::Duration;
use crate::policies::{BackoffPolicy, RestartPolicy};
#[derive(Clone, Debug)]
pub struct SupervisorConfig {
pub grace: Duration,
pub max_concurrent: usize,
pub bus_capacity: usize,
pub restart: RestartPolicy,
pub backoff: BackoffPolicy,
pub timeout: Duration,
pub max_retries: u32,
}
impl SupervisorConfig {
pub fn validate(&self) -> Result<(), &'static str> {
if self.bus_capacity == 0 {
return Err("bus_capacity must be > 0");
}
Ok(())
}
#[inline]
pub fn concurrency_limit(&self) -> Option<usize> {
if self.max_concurrent == 0 {
None
} else {
Some(self.max_concurrent)
}
}
#[inline]
pub fn default_timeout(&self) -> Option<Duration> {
if self.timeout == Duration::ZERO {
None
} else {
Some(self.timeout)
}
}
#[inline]
pub fn bus_capacity_clamped(&self) -> usize {
self.bus_capacity.max(1)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn validate_rejects_zero_bus_capacity() {
let mut cfg = SupervisorConfig::default();
cfg.bus_capacity = 0;
assert!(cfg.validate().is_err());
}
#[test]
fn validate_accepts_default() {
assert!(SupervisorConfig::default().validate().is_ok());
}
#[test]
fn concurrency_limit_zero_means_unlimited() {
let cfg = SupervisorConfig {
max_concurrent: 0,
..Default::default()
};
assert_eq!(cfg.concurrency_limit(), None);
}
#[test]
fn concurrency_limit_nonzero() {
let cfg = SupervisorConfig {
max_concurrent: 4,
..Default::default()
};
assert_eq!(cfg.concurrency_limit(), Some(4));
}
#[test]
fn default_timeout_zero_means_none() {
let cfg = SupervisorConfig::default();
assert_eq!(cfg.default_timeout(), None);
}
#[test]
fn default_timeout_nonzero() {
let cfg = SupervisorConfig {
timeout: Duration::from_secs(30),
..Default::default()
};
assert_eq!(cfg.default_timeout(), Some(Duration::from_secs(30)));
}
#[test]
fn bus_capacity_clamped_never_zero() {
let cfg = SupervisorConfig {
bus_capacity: 0,
..Default::default()
};
assert_eq!(cfg.bus_capacity_clamped(), 1);
}
}
impl Default for SupervisorConfig {
fn default() -> Self {
Self {
grace: Duration::from_secs(60),
max_concurrent: 0,
bus_capacity: 1024,
timeout: Duration::from_secs(0),
restart: RestartPolicy::default(),
backoff: BackoffPolicy::default(),
max_retries: 0,
}
}
}