1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
use std::any::type_name_of_val;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use async_trait::async_trait;
use config::Config;
use log::debug;
use tokio::runtime::Runtime;
use crate::core::Error;

#[async_trait]
pub trait Runner {
    fn name(&self) -> &str {
        let name = type_name_of_val(self);
        match name.rsplit_once("::") {
            None => name,
            Some((_, name)) => name
        }
    }

    fn runtime(&self, _config: Arc<Config>) -> Result<Runtime, Error> {
        debug!("create tokio Runtime for {} runner", self.name());
        let pool = self.name().to_lowercase();
        tokio::runtime::Builder::new_multi_thread()
            .thread_name_fn(move || {
                static SEQ: AtomicUsize = AtomicUsize::new(0);
                let pool = pool.clone();
                format!("{}-{}", &pool, SEQ.fetch_add(1, Ordering::SeqCst))
            })
            .enable_all()
            .build()
            .map_err(|_e| Error::from(format!("cannot initialize runtime for runner {}", self.name())))
    }

    async fn run(&self) -> Result<(), Error>;
}