server-watchdog 0.1.2

A server monitoring and remote control tool via messenger.
Documentation
use std::collections::HashMap;
use std::time::Duration;
use tokio::task::JoinHandle;
use crate::application::worker::Worker;

pub struct WorkerRunner {
    handles: HashMap<String, JoinHandle<()>>
}

impl WorkerRunner {
    pub fn new() -> Self {
        Self {
            handles: HashMap::new()
        }
    }

    pub fn stop(&mut self, key: &str) {
        let handle = match self.handles.get_mut(key) {
            Some(handle) => handle,
            None => return
        };
        handle.abort();
        self.handles.remove(key);
    }

    pub fn run_batch(&mut self, workers: Vec<Box<dyn Worker>>) {
        for worker in workers.into_iter() {
            self.run(worker);
        }
    }

    pub fn run(&mut self, mut worker: Box<dyn Worker>) {
        let key = worker.get_name().to_string();
        let handle = tokio::spawn(async move {
            let mut interval = tokio::time::interval(Duration::from_secs(worker.interval() as u64));

            loop {
                interval.tick().await;
                if !worker.on_tick().await {
                    break;
                }
            }
        });
        self.handles.insert(key, handle);
    }
}

#[cfg(test)]
mod tests {
    use std::env;
    use dotenv::dotenv;
    use dyn_clone::clone_trait_object;
    use tokio::sync::mpsc;
    use crate::domain::config::{ClientConfig};
    use crate::infrastructure::client;
    use crate::infrastructure::client::common::{Client};
    use crate::application::worker::runner::{ WorkerRunner};

    #[tokio::test]
    async fn run_work() {
        dotenv().ok();
        let token = env::var("TELEGRAM_TOKEN").unwrap();
        let mut registry = WorkerRunner::new();
        let mut client = client::from(
            ClientConfig::new_telegram("name", token.as_str())).unwrap();

        let (tx, mut rx) = mpsc::channel(16);
        client.subscribe(tx);
        let client_for_callback = client.clone();
        tokio::spawn(async move {
            loop {
                match rx.recv().await {
                    Some(message) => {
                        let chat_id_owned = message.chat_id;
                        let text_owned = message.data;
                        client_for_callback.send_message(chat_id_owned.as_str(), format!("echo {chat_id_owned}: {text_owned}").as_str()).await;
                    },
                    None => {
                        break;
                    }
                }
            }
        });
        registry.run(client);
        tokio::signal::ctrl_c().await.unwrap();
    }
}