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>;
}