hatchery_server/
supervisor.rs1use crate::error::ServerError;
4use crate::subservice::{Status, Subservice};
5use std::sync::{Arc, Mutex};
6
7#[derive(Clone)]
8pub struct Supervisor {
9 inner: Arc<Mutex<Vec<Box<dyn Subservice>>>>,
10}
11
12impl Supervisor {
13 pub fn new(subservices: Vec<Box<dyn Subservice>>) -> Self {
14 Self { inner: Arc::new(Mutex::new(subservices)) }
15 }
16
17 pub fn start_autostart(&self) -> Vec<(&'static str, ServerError)> {
20 let mut failures = Vec::new();
21 let mut guard = self.inner.lock().unwrap_or_else(|p| p.into_inner());
22 for service in guard.iter_mut().filter(|s| !s.on_demand()) {
23 if let Err(error) = service.start() {
24 failures.push((service.name(), error));
25 }
26 }
27 failures
28 }
29
30 pub fn start_named(&self, name: &str) -> Result<Status, ServerError> {
32 let mut guard = self.inner.lock().unwrap_or_else(|p| p.into_inner());
33 let service = guard
34 .iter_mut()
35 .find(|s| s.name() == name)
36 .ok_or_else(|| ServerError::Config(format!("unknown subservice {name}")))?;
37 service.start()?;
38 Ok(service.status())
39 }
40
41 pub fn stop_named(&self, name: &str) -> Result<Status, ServerError> {
42 let mut guard = self.inner.lock().unwrap_or_else(|p| p.into_inner());
43 let service = guard
44 .iter_mut()
45 .find(|s| s.name() == name)
46 .ok_or_else(|| ServerError::Config(format!("unknown subservice {name}")))?;
47 service.stop();
48 Ok(service.status())
49 }
50
51 pub fn statuses(&self) -> Vec<Status> {
52 let mut guard = self.inner.lock().unwrap_or_else(|p| p.into_inner());
53 guard.iter_mut().map(|s| s.status()).collect()
54 }
55
56 pub fn stop_all(&self) {
57 let mut guard = self.inner.lock().unwrap_or_else(|p| p.into_inner());
58 for service in guard.iter_mut() {
59 service.stop();
60 }
61 }
62}