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