use std::sync::Arc;
use tokio::{sync, sync::mpsc};
use super::{alive::AliveTracker, registry::Registry, supervisor::Supervisor};
use crate::{
core::SupervisorConfig,
events::Bus,
subscribers::{Subscribe, SubscriberSet},
};
pub struct SupervisorBuilder {
cfg: SupervisorConfig,
subscribers: Vec<Arc<dyn Subscribe>>,
#[cfg(feature = "controller")]
controller_config: Option<crate::controller::ControllerConfig>,
}
impl SupervisorBuilder {
pub fn new(cfg: SupervisorConfig) -> Self {
Self {
cfg,
subscribers: Vec::new(),
#[cfg(feature = "controller")]
controller_config: None,
}
}
pub fn with_subscribers(mut self, subscribers: Vec<Arc<dyn Subscribe>>) -> Self {
self.subscribers = subscribers;
self
}
#[cfg(feature = "controller")]
pub fn with_controller(mut self, config: crate::controller::ControllerConfig) -> Self {
self.controller_config = Some(config);
self
}
pub fn build(self) -> Arc<Supervisor> {
let bus = Bus::new(self.cfg.bus_capacity_clamped());
let subs = Arc::new(SubscriberSet::new(self.subscribers, bus.clone()));
let runtime_token = tokio_util::sync::CancellationToken::new();
let semaphore = self
.cfg
.concurrency_limit()
.map(sync::Semaphore::new)
.map(Arc::new);
let (cmd_tx, cmd_rx) = mpsc::unbounded_channel();
let registry = Registry::new(bus.clone(), runtime_token.clone(), semaphore, cmd_rx);
let alive = Arc::new(AliveTracker::new());
let sup = Arc::new(Supervisor::new_internal(
self.cfg,
bus.clone(),
subs,
alive,
registry,
runtime_token.clone(),
cmd_tx,
));
#[cfg(feature = "controller")]
if let Some(ctrl_cfg) = self.controller_config {
let controller = crate::controller::Controller::new(ctrl_cfg, &sup, bus.clone());
let _ = sup.controller.set(Arc::clone(&controller));
controller.run(runtime_token.clone());
}
sup
}
}