Skip to main content

server_watchdog/application/worker/
runner.rs

1use std::collections::HashMap;
2use std::time::Duration;
3use tokio::task::JoinHandle;
4use crate::application::worker::Worker;
5
6pub struct WorkerRunner {
7    handles: HashMap<String, JoinHandle<()>>
8}
9
10impl WorkerRunner {
11    pub fn new() -> Self {
12        Self {
13            handles: HashMap::new()
14        }
15    }
16
17    pub fn stop(&mut self, key: &str) {
18        let handle = match self.handles.get_mut(key) {
19            Some(handle) => handle,
20            None => return
21        };
22        handle.abort();
23        self.handles.remove(key);
24    }
25
26    pub fn run_batch(&mut self, workers: Vec<Box<dyn Worker>>) {
27        for worker in workers.into_iter() {
28            self.run(worker);
29        }
30    }
31
32    pub fn run(&mut self, mut worker: Box<dyn Worker>) {
33        let key = worker.get_name().to_string();
34        let handle = tokio::spawn(async move {
35            let mut interval = tokio::time::interval(Duration::from_secs(worker.interval() as u64));
36
37            loop {
38                interval.tick().await;
39                if !worker.on_tick().await {
40                    break;
41                }
42            }
43        });
44        self.handles.insert(key, handle);
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use std::env;
51    use dotenv::dotenv;
52    use dyn_clone::clone_trait_object;
53    use tokio::sync::mpsc;
54    use crate::domain::config::{ClientConfig};
55    use crate::infrastructure::client;
56    use crate::infrastructure::client::common::{Client};
57    use crate::application::worker::runner::{ WorkerRunner};
58
59    #[tokio::test]
60    async fn run_work() {
61        dotenv().ok();
62        let token = env::var("TELEGRAM_TOKEN").unwrap();
63        let mut registry = WorkerRunner::new();
64        let mut client = client::from(
65            ClientConfig::new_telegram("name", token.as_str())).unwrap();
66
67        let (tx, mut rx) = mpsc::channel(16);
68        client.subscribe(tx);
69        let client_for_callback = client.clone();
70        tokio::spawn(async move {
71            loop {
72                match rx.recv().await {
73                    Some(message) => {
74                        let chat_id_owned = message.chat_id;
75                        let text_owned = message.data;
76                        client_for_callback.send_message(chat_id_owned.as_str(), format!("echo {chat_id_owned}: {text_owned}").as_str()).await;
77                    },
78                    None => {
79                        break;
80                    }
81                }
82            }
83        });
84        registry.run(client);
85        tokio::signal::ctrl_c().await.unwrap();
86    }
87}