xref: /DragonReach/src/executor/mod.rs (revision af4e087250481d24f7a6ee7057d648c56a4753e3)
1e5a8055aSGnoCiYeH pub mod dep_graph;
2e5a8055aSGnoCiYeH pub mod service_executor;
3e5a8055aSGnoCiYeH 
4e5a8055aSGnoCiYeH use crate::{
5e5a8055aSGnoCiYeH     error::runtime_error::{RuntimeError, RuntimeErrorType},
617ae4661SGnoCiYeH     manager::UnitManager,
7909e4d10SGnoCiYeH     unit::UnitState,
8e5a8055aSGnoCiYeH };
9e5a8055aSGnoCiYeH 
1076992bdbSGnoCiYeH #[allow(dead_code)]
1117ae4661SGnoCiYeH #[derive(Debug, Clone, Copy)]
1217ae4661SGnoCiYeH pub enum ExitStatus {
13b40b6b4dSGnoCiYeH     Success,  // 成功退出
14b40b6b4dSGnoCiYeH     Failure,  // 启动失败
15b40b6b4dSGnoCiYeH     Abnormal, // 异常退出
16b40b6b4dSGnoCiYeH     Abort,    // 显式退出
17b40b6b4dSGnoCiYeH     Watchdog, // 超时检测
1817ae4661SGnoCiYeH }
1917ae4661SGnoCiYeH 
2017ae4661SGnoCiYeH impl ExitStatus {
2117ae4661SGnoCiYeH     /// ## 从错误码获得退出状态
2217ae4661SGnoCiYeH     ///
2317ae4661SGnoCiYeH     /// 注意,该方法只会返回Success(exit_code == 0)和Abnormal(exit_code != 0)两种状态
2417ae4661SGnoCiYeH     /// 其他DragonReach定义的退出状态需要手动指定
2517ae4661SGnoCiYeH     ///
2617ae4661SGnoCiYeH     /// ### return Success(exit_code == 0)、Abnormal(exit_code != 0)
from_exit_code(exit_code: i32) -> Self2717ae4661SGnoCiYeH     pub fn from_exit_code(exit_code: i32) -> Self {
2817ae4661SGnoCiYeH         match exit_code {
2917ae4661SGnoCiYeH             0 => return Self::Success,
3017ae4661SGnoCiYeH             _ => return Self::Abnormal,
3117ae4661SGnoCiYeH         }
3217ae4661SGnoCiYeH     }
3317ae4661SGnoCiYeH }
3417ae4661SGnoCiYeH 
35e5a8055aSGnoCiYeH //Unit的全局执行器
36e5a8055aSGnoCiYeH pub struct Executor;
37e5a8055aSGnoCiYeH 
38e5a8055aSGnoCiYeH impl Executor {
39b40b6b4dSGnoCiYeH     /// ## 全局执行器入口,将会进行启动检测以及循环依赖检测
exec(unit_id: usize) -> Result<(), RuntimeError>40b40b6b4dSGnoCiYeH     pub fn exec(unit_id: usize) -> Result<(), RuntimeError> {
41b40b6b4dSGnoCiYeH         // TODO: 添加超时检测,这个工作应该在线程执行
42e5a8055aSGnoCiYeH 
43909e4d10SGnoCiYeH         {
44909e4d10SGnoCiYeH             // 设置Unit状态为正在启动
45909e4d10SGnoCiYeH             // TODO: 目前单线程工作这样设置是无意义的
46909e4d10SGnoCiYeH             UnitManager::get_unit_with_id(&unit_id)
47909e4d10SGnoCiYeH                 .unwrap()
48909e4d10SGnoCiYeH                 .lock()
49909e4d10SGnoCiYeH                 .unwrap()
50909e4d10SGnoCiYeH                 .unit_base_mut()
51909e4d10SGnoCiYeH                 .set_state(UnitState::Activating);
52909e4d10SGnoCiYeH         }
53b40b6b4dSGnoCiYeH         match Self::exec_(unit_id) {
54909e4d10SGnoCiYeH             Ok(_) => {
55909e4d10SGnoCiYeH                 UnitManager::get_unit_with_id(&unit_id)
56909e4d10SGnoCiYeH                     .unwrap()
57909e4d10SGnoCiYeH                     .lock()
58909e4d10SGnoCiYeH                     .unwrap()
59909e4d10SGnoCiYeH                     .unit_base_mut()
60909e4d10SGnoCiYeH                     .set_state(UnitState::Active);
61909e4d10SGnoCiYeH                 Ok(())
62*d70ac4edSGnoCiYeH             }
63b40b6b4dSGnoCiYeH             Err(e) => {
64b40b6b4dSGnoCiYeH                 let mutex = UnitManager::get_unit_with_id(&unit_id).unwrap();
65b40b6b4dSGnoCiYeH                 let mut unit = mutex.lock().unwrap();
66b40b6b4dSGnoCiYeH 
67b40b6b4dSGnoCiYeH                 // 启动失败时启动onfailure项目
68b40b6b4dSGnoCiYeH                 for id in unit.unit_base().unit_part().on_failure() {
69b40b6b4dSGnoCiYeH                     // TODO: 待日志库开发后,这里的错误处理应该是打印日志
70b40b6b4dSGnoCiYeH                     let _ = Executor::exec(*id);
71b40b6b4dSGnoCiYeH                 }
72b40b6b4dSGnoCiYeH 
73909e4d10SGnoCiYeH                 unit.unit_base_mut().set_state(UnitState::Failed);
74b40b6b4dSGnoCiYeH                 unit.after_exit(ExitStatus::Failure);
75b40b6b4dSGnoCiYeH                 return Err(e);
76b40b6b4dSGnoCiYeH             }
77b40b6b4dSGnoCiYeH         }
78b40b6b4dSGnoCiYeH     }
exec_(unit_id: usize) -> Result<(), RuntimeError>79b40b6b4dSGnoCiYeH     pub fn exec_(unit_id: usize) -> Result<(), RuntimeError> {
80b40b6b4dSGnoCiYeH         // TODO: 目前的启动逻辑还是串行启动,后续需更改为并行启动某些项
81b40b6b4dSGnoCiYeH 
82b40b6b4dSGnoCiYeH         let unit = match UnitManager::get_unit_with_id(&unit_id) {
83b40b6b4dSGnoCiYeH             Some(s) => s,
84b40b6b4dSGnoCiYeH             None => {
85b40b6b4dSGnoCiYeH                 return Err(RuntimeError::new(RuntimeErrorType::FileNotFound));
86b40b6b4dSGnoCiYeH             }
87b40b6b4dSGnoCiYeH         };
88b40b6b4dSGnoCiYeH 
89b40b6b4dSGnoCiYeH         let mut unit = unit.lock().unwrap();
90b40b6b4dSGnoCiYeH 
91b40b6b4dSGnoCiYeH         //TODO: 优化此处,解析时也用到了拓扑排序,尝试使用那次拓扑排序的结果
92b40b6b4dSGnoCiYeH         // 此处不需要再次拓扑排序,在parse时已经确定不会出现循环依赖,现在仅需按照启动流程启动即可
93b40b6b4dSGnoCiYeH         // let mut graph = DepGraph::construct_graph(&unit);
94b40b6b4dSGnoCiYeH         // let sort_ret = graph.topological_sort()?;
95b40b6b4dSGnoCiYeH 
96b40b6b4dSGnoCiYeH         // 优先启动After
97b40b6b4dSGnoCiYeH         for u in unit.unit_base().unit_part().after() {
9817ae4661SGnoCiYeH             if UnitManager::is_running_unit(&u) {
9917ae4661SGnoCiYeH                 continue;
10017ae4661SGnoCiYeH             }
10117ae4661SGnoCiYeH             let mutex = UnitManager::get_unit_with_id(&u).unwrap();
102b40b6b4dSGnoCiYeH             let mut after = mutex.lock().unwrap();
103b40b6b4dSGnoCiYeH             after.run()?;
104e5a8055aSGnoCiYeH         }
105b40b6b4dSGnoCiYeH 
106b40b6b4dSGnoCiYeH         // 启动Requires
107b40b6b4dSGnoCiYeH         for u in unit.unit_base().unit_part().requires() {
108b40b6b4dSGnoCiYeH             if UnitManager::is_running_unit(&u) {
109b40b6b4dSGnoCiYeH                 continue;
110e5a8055aSGnoCiYeH             }
111b40b6b4dSGnoCiYeH             let mutex = UnitManager::get_unit_with_id(&u).unwrap();
112b40b6b4dSGnoCiYeH             let mut after = mutex.lock().unwrap();
113b40b6b4dSGnoCiYeH             after.run()?;
114b40b6b4dSGnoCiYeH         }
115b40b6b4dSGnoCiYeH 
116b40b6b4dSGnoCiYeH         // 启动binds
117b40b6b4dSGnoCiYeH         for u in unit.unit_base().unit_part().binds_to() {
118b40b6b4dSGnoCiYeH             if UnitManager::is_running_unit(&u) {
119b40b6b4dSGnoCiYeH                 continue;
120b40b6b4dSGnoCiYeH             }
121b40b6b4dSGnoCiYeH             let mutex = UnitManager::get_unit_with_id(&u).unwrap();
122b40b6b4dSGnoCiYeH             let mut after = mutex.lock().unwrap();
123b40b6b4dSGnoCiYeH             after.run()?;
124b40b6b4dSGnoCiYeH         }
125b40b6b4dSGnoCiYeH 
126b40b6b4dSGnoCiYeH         // 启动Wants
127b40b6b4dSGnoCiYeH         for u in unit.unit_base().unit_part().wants() {
128b40b6b4dSGnoCiYeH             if UnitManager::is_running_unit(&u) {
129b40b6b4dSGnoCiYeH                 continue;
130b40b6b4dSGnoCiYeH             }
131b40b6b4dSGnoCiYeH             let mutex = UnitManager::get_unit_with_id(&u).unwrap();
132b40b6b4dSGnoCiYeH             let mut after = mutex.lock().unwrap();
133b40b6b4dSGnoCiYeH             let _ = after.run();
134b40b6b4dSGnoCiYeH         }
135b40b6b4dSGnoCiYeH 
136b40b6b4dSGnoCiYeH         // 启动自身
137b40b6b4dSGnoCiYeH         unit.run()?;
138e5a8055aSGnoCiYeH         return Ok(());
139e5a8055aSGnoCiYeH     }
140909e4d10SGnoCiYeH 
restart(id: usize) -> Result<(), RuntimeError>141909e4d10SGnoCiYeH     pub fn restart(id: usize) -> Result<(), RuntimeError> {
142909e4d10SGnoCiYeH         if let Some(unit) = UnitManager::get_unit_with_id(&id) {
143909e4d10SGnoCiYeH             unit.lock().unwrap().restart()?;
144909e4d10SGnoCiYeH         }
145909e4d10SGnoCiYeH         Ok(())
146909e4d10SGnoCiYeH     }
147e5a8055aSGnoCiYeH }
148