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