depl 2.4.3

Toolkit for a bunch of local and remote CI/CD actions
Documentation
//! Daemons module.

use async_process::Child;
use std::sync::Arc;
use tokio::sync::Mutex;

/// Current Pipeline's daemons.
#[derive(Clone)]
pub struct Daemons(Arc<Mutex<Option<Vec<Daemon>>>>);

/// Single daemon.
pub struct Daemon(Child);

impl Default for Daemons {
  fn default() -> Self {
    Self(Arc::new(Mutex::new(Some(Vec::new()))))
  }
}

impl Daemons {
  /// Adds new daemon.
  pub async fn add_daemon(&self, child: Child) {
    let mut guard = self.0.lock().await;
    if let Some(v) = guard.as_mut() {
      v.push(Daemon(child));
    } else {
      *guard = Some(vec![Daemon(child)])
    }
  }

  /// Shutdowns all daemons.
  pub async fn shutdown(&mut self) {
    let daemons = {
      let mut guard = self.0.lock().await;
      guard.take().unwrap_or_default()
    };

    for mut daemon in daemons.into_iter() {
      daemon.shutdown().await;
    }
  }
}

impl Daemon {
  async fn shutdown(&mut self) {
    tokio::select! {
      _ = tokio::time::sleep(tokio::time::Duration::from_secs(10)) => {
        let _ = self.0.kill();
      }
      _ = self.0.status() => {},
    }
  }
}