use crate::service::Service;
use crate::utils;
use log::*;
pub struct ServiceManager {
services: Vec<Box<Service>>
}
impl ServiceManager {
pub fn new() -> Self {
ServiceManager {
services: Vec::new(),
}
}
pub fn register(&mut self, service_box: Box<Service>) {
debug!("Registering: {}", service_box.as_ref().name());
self.services.push(service_box);
}
pub fn await_termination_signal_then_stop(&mut self) {
utils::await_for_process_termination_signal();
self.stop_and_await();
}
fn apply_ordered<F>(&mut self, closure: F) where F: Fn(&mut Box<Service>) -> () {
self.services
.iter_mut()
.for_each(closure);
}
fn apply_reversed<F>(&mut self, closure: F) where F: FnMut(&mut Box<Service>) -> () {
self.services
.iter_mut()
.rev()
.for_each(closure);
}
}
const SERVICE_MANAGER_SERVICE_NAME: &'static str = "srvzio::ServiceManager";
impl Service for ServiceManager {
fn name(&self) -> &'static str {
SERVICE_MANAGER_SERVICE_NAME
}
fn start(&mut self) {
self.apply_ordered(|s: &mut Box<Service>| {
debug!("Starting: {}", s.name());
s.start()
});
}
fn await_started(&mut self) {
self.apply_ordered(|s: &mut Box<Service>| {
debug!("Awaiting started: {}", s.name());
s.await_started()
});
}
fn start_and_await(&mut self) {
self.apply_ordered(|s: &mut Box<Service>| s.start_and_await());
}
fn stop(&mut self) {
self.apply_reversed(|s: &mut Box<Service>| {
debug!("Stopping: {}", s.name());
s.stop()
});
}
fn await_stopped(&mut self) {
self.apply_reversed(|s: &mut Box<Service>| {
debug!("Awaiting stopped: {}", s.name());
s.await_stopped()
});
}
fn stop_and_await(&mut self) {
self.apply_reversed(|s: &mut Box<Service>| s.stop_and_await());
}
}