use std::error::Error;
use std::sync::{Arc, Mutex};
use simple_error::*;
use grapeTimerR::timer;
use std::time;
use log::*;
use crate::config::ActionConf;
use crate::action_http::new_http;
use crate::action_ping::new_ping;
use crate::action_tcp::new_tcp;
use crate::action_ws::new_websocket;
use crate::action_do::{executor_fail, executor_recover};
pub struct ActionData {
pub id:i32,
pub name:String,
pub task_action:ActionConf,
pub fail_count:i32,
pub fail_state:bool,
}
impl ActionData {
pub fn do_failed(&mut self) {
self.fail_state = true;
self.fail_count+=1;
let task_conf = &self.task_action;
if self.fail_count >= task_conf.fail_count {
executor_fail(task_conf);
}
}
pub fn do_recover(&mut self) {
if self.fail_state {
self.fail_count = 0;
self.fail_state = false;
let task_conf = self.get_conf();
executor_recover(task_conf);
}
}
pub fn get_conf(&self) -> &ActionConf {
return &self.task_action;
}
}
pub trait ActionTrait : Send+Sync {
fn id(&self) -> i32;
fn name(&self) -> &str;
fn append_data(&mut self,data:ActionData);
fn executor(&mut self);
}
pub fn new_action(task:&ActionConf) -> Result<Arc<Mutex<dyn ActionTrait>>,Box<dyn Error>> {
let napp_data = ActionData{
id: task.id,
name: task.name.clone(),
task_action: task.clone(),
fail_count:0,
fail_state:false,
};
info!("build task action:{} id:{} type:{}...",task.name,task.id,task.atype);
let ntype = task.atype.clone();
match ntype.as_str() {
"http"=> {
Ok(Arc::new(Mutex::new(new_http(napp_data))))
}
"ping" => {
Ok(Arc::new(Mutex::new(new_ping(napp_data))))
}
"tcp" | "tcp_tls" => {
Ok(Arc::new(Mutex::new(new_tcp(napp_data))))
}
"websocket" => {
Ok(Arc::new(Mutex::new(new_websocket(napp_data))))
}
_ => {
bail!("error action type...")
}
}
}
pub fn spawn_action(task:&ActionConf) -> Result<(),Box<dyn Error>> {
let mut action_trait = new_action(task)?;
info!("start task:{} id:{} type:{}...",task.name,task.id,task.atype);
let r = timer::spawn_ticker(time::Duration::from_millis(task.tick as u64),
task.count,move |ixd| {
action_trait.lock().unwrap().executor();
});
match r {
Ok(x) => { Ok(()) }
Err(e) => { bail!(e.to_string()) }
}
}