1 pub mod dep_graph; 2 pub mod service_executor; 3 4 use crate::{ 5 error::runtime_error::{RuntimeError, RuntimeErrorType}, 6 manager::UnitManager, 7 unit::Unit, 8 }; 9 10 #[derive(Debug, Clone, Copy)] 11 pub enum ExitStatus { 12 Success, // 成功退出 13 Failure, // 启动失败 14 Abnormal, // 异常退出 15 Abort, // 显式退出 16 Watchdog, // 超时检测 17 } 18 19 impl ExitStatus { 20 /// ## 从错误码获得退出状态 21 /// 22 /// 注意,该方法只会返回Success(exit_code == 0)和Abnormal(exit_code != 0)两种状态 23 /// 其他DragonReach定义的退出状态需要手动指定 24 /// 25 /// ### return Success(exit_code == 0)、Abnormal(exit_code != 0) 26 pub fn from_exit_code(exit_code: i32) -> Self { 27 match exit_code { 28 0 => return Self::Success, 29 _ => return Self::Abnormal, 30 } 31 } 32 } 33 34 //Unit的全局执行器 35 pub struct Executor; 36 37 impl Executor { 38 /// ## 全局执行器入口,将会进行启动检测以及循环依赖检测 39 pub fn exec(unit_id: usize) -> Result<(), RuntimeError> { 40 // TODO: 添加超时检测,这个工作应该在线程执行 41 42 match Self::exec_(unit_id) { 43 Ok(_) => Ok(()), 44 Err(e) => { 45 let mutex = UnitManager::get_unit_with_id(&unit_id).unwrap(); 46 let mut unit = mutex.lock().unwrap(); 47 48 // 启动失败时启动onfailure项目 49 for id in unit.unit_base().unit_part().on_failure() { 50 // TODO: 待日志库开发后,这里的错误处理应该是打印日志 51 let _ = Executor::exec(*id); 52 } 53 54 unit.after_exit(ExitStatus::Failure); 55 return Err(e); 56 } 57 } 58 } 59 pub fn exec_(unit_id: usize) -> Result<(), RuntimeError> { 60 // TODO: 目前的启动逻辑还是串行启动,后续需更改为并行启动某些项 61 62 let unit = match UnitManager::get_unit_with_id(&unit_id) { 63 Some(s) => s, 64 None => { 65 return Err(RuntimeError::new(RuntimeErrorType::FileNotFound)); 66 } 67 }; 68 69 let mut unit = unit.lock().unwrap(); 70 71 //TODO: 优化此处,解析时也用到了拓扑排序,尝试使用那次拓扑排序的结果 72 // 此处不需要再次拓扑排序,在parse时已经确定不会出现循环依赖,现在仅需按照启动流程启动即可 73 // let mut graph = DepGraph::construct_graph(&unit); 74 // let sort_ret = graph.topological_sort()?; 75 76 // 优先启动After 77 for u in unit.unit_base().unit_part().after() { 78 if UnitManager::is_running_unit(&u) { 79 continue; 80 } 81 82 let mutex = UnitManager::get_unit_with_id(&u).unwrap(); 83 let mut after = mutex.lock().unwrap(); 84 after.run()?; 85 } 86 87 // 启动Requires 88 for u in unit.unit_base().unit_part().requires() { 89 if UnitManager::is_running_unit(&u) { 90 continue; 91 } 92 let mutex = UnitManager::get_unit_with_id(&u).unwrap(); 93 let mut after = mutex.lock().unwrap(); 94 after.run()?; 95 } 96 97 // 启动binds 98 for u in unit.unit_base().unit_part().binds_to() { 99 if UnitManager::is_running_unit(&u) { 100 continue; 101 } 102 let mutex = UnitManager::get_unit_with_id(&u).unwrap(); 103 let mut after = mutex.lock().unwrap(); 104 after.run()?; 105 } 106 107 // 启动Wants 108 for u in unit.unit_base().unit_part().wants() { 109 if UnitManager::is_running_unit(&u) { 110 continue; 111 } 112 let mutex = UnitManager::get_unit_with_id(&u).unwrap(); 113 let mut after = mutex.lock().unwrap(); 114 let _ = after.run(); 115 } 116 117 // 启动自身 118 unit.run()?; 119 return Ok(()); 120 } 121 } 122