@@ -7,92 +7,106 @@ pub use unit_manager::*;
77use crate :: executor:: ExitStatus ;
88
99use self :: timer_manager:: TimerManager ;
10-
10+ use crate :: unit:: signal:: SIGCHILD_SIGNAL_RECEIVED ;
11+ use nix:: sys:: wait:: { waitpid, WaitPidFlag , WaitStatus } ;
12+ use nix:: unistd:: Pid ;
13+ use std:: sync:: atomic:: Ordering ;
1114pub struct Manager ;
1215
1316impl Manager {
14- /// ## 检查当前DragonReach运行的项目状态 ,并对其分发处理
17+ /// ## 检查当前 DragonReach 运行的项目状态 ,并对其分发处理
1518 pub fn check_running_status ( ) {
16- // 检查正在运行的Unit
17- let mut running_manager = RUNNING_TABLE . write ( ) . unwrap ( ) ;
18- let mut exited_unit: Vec < ( usize , ExitStatus ) > = Vec :: new ( ) ;
19- for unit in running_manager. mut_running_table ( ) {
20- let proc = unit. 1 ;
21- match proc. try_wait ( ) {
22- //进程正常退出
23- Ok ( Some ( status) ) => {
24- exited_unit. push ( (
25- * unit. 0 ,
26- ExitStatus :: from_exit_code ( status. code ( ) . unwrap_or ( 0 ) ) ,
27- ) ) ;
28- }
29- //进程错误退出(或启动失败)
30- Err ( e) => {
31- eprintln ! ( "unit error: {}" , e) ;
32-
33- //test
34- exited_unit. push ( ( * unit. 0 , ExitStatus :: from_exit_code ( !0 ) ) ) ;
19+ if SIGCHILD_SIGNAL_RECEIVED
20+ . compare_exchange ( true , false , Ordering :: SeqCst , Ordering :: SeqCst )
21+ . is_ok ( )
22+ {
23+ let mut exited_unit: Vec < ( usize , ExitStatus ) > = Vec :: new ( ) ;
24+ let mut running_manager = RUNNING_TABLE . write ( ) . unwrap ( ) ;
25+ // 检查所有运行中的 Unit
26+ for unit in running_manager. mut_running_table ( ) {
27+ let pid = Pid :: from_raw ( unit. 1 . id ( ) as i32 ) ;
28+ // 检查 Unit 的运行状态
29+ match waitpid ( Some ( pid) , Some ( WaitPidFlag :: WNOHANG ) ) {
30+ // 若 Unit 为正常退出,则将其加入退出列表
31+ Ok ( WaitStatus :: Exited ( _, status) ) => {
32+ exited_unit. push ( ( * unit. 0 , ExitStatus :: from_exit_code ( status) ) ) ;
33+ }
34+ // 若 Unit 为被信号终止,则将其加入退出列表,并输出日志
35+ Ok ( WaitStatus :: Signaled ( _, signal, _) ) => {
36+ eprintln ! ( "unit terminated by signal: {}" , signal) ;
37+ exited_unit. push ( ( * unit. 0 , ExitStatus :: from_exit_code ( !0 ) ) ) ;
38+ }
39+ // 其他错误情况
40+ Err ( _) => {
41+ eprintln ! ( "unit waitpid error" ) ;
42+ }
43+ // 若 Unit 正常运行,则不做处理
44+ Ok ( _) => { }
3545 }
36- //进程处于正常运行状态
37- _ => { }
3846 }
39- }
40- //释放锁,以便后续删除操作能拿到锁
41- drop ( running_manager) ;
4247
43- // 处理退出的Unit
44- for tmp in exited_unit {
45- // 从运行表中擦除该unit
46- UnitManager :: remove_running ( tmp. 0 ) ;
48+ drop ( running_manager) ;
4749
48- // 取消该任务的定时器任务
49- TimerManager :: cancel_timer ( tmp. 0 ) ;
50+ // 处理退出的 Unit
51+ for tmp in exited_unit {
52+ // 将该任务从运行表中移除
53+ UnitManager :: remove_running ( tmp. 0 ) ;
5054
51- let _ = UnitManager :: get_unit_with_id ( & tmp. 0 )
52- . unwrap ( )
53- . lock ( )
54- . unwrap ( )
55- . exit ( ) ; //交付给相应类型的Unit类型去执行退出后的逻辑
55+ // 取消该任务的定时器任务
56+ TimerManager :: cancel_timer ( tmp. 0 ) ;
5657
57- TimerManager :: update_next_trigger ( tmp. 0 , false ) ; //更新所有归属于此unit的计时器
58+ // 交付处理子进程退出逻辑
59+ let _ = UnitManager :: get_unit_with_id ( & tmp. 0 )
60+ . unwrap ( )
61+ . lock ( )
62+ . unwrap ( )
63+ . exit ( ) ;
5864
59- // 交付处理子进程退出逻辑
60- let unit = UnitManager :: get_unit_with_id ( & tmp. 0 ) . unwrap ( ) ;
61- unit. lock ( ) . unwrap ( ) . after_exit ( tmp. 1 ) ;
62- }
65+ // 更新属于该 Unit 的定时器任务
66+ TimerManager :: update_next_trigger ( tmp. 0 , false ) ;
6367
64- // 若无运行中任务,则取出IDLE任务运行
65- if UnitManager :: running_count ( ) == 0 {
66- let unit = UnitManager :: pop_a_idle_service ( ) ;
67- match unit {
68- Some ( unit) => {
68+ // 交付处理子进程退出后逻辑
69+ let unit = UnitManager :: get_unit_with_id ( & tmp. 0 ) . unwrap ( ) ;
70+ unit. lock ( ) . unwrap ( ) . after_exit ( tmp. 1 ) ;
71+ }
72+ // 若无运行中任务,则取出 IDLE 任务运行
73+ if UnitManager :: running_count ( ) == 0 {
74+ if let Some ( unit) = UnitManager :: pop_a_idle_service ( ) {
6975 let _ = unit. lock ( ) . unwrap ( ) . run ( ) ;
7076 }
71- None => { }
7277 }
7378 }
7479 }
7580
7681 /// ## 检查当前所有cmd进程的运行状态
7782 pub fn check_cmd_proc ( ) {
78- let mut exited = Vec :: new ( ) ;
79- let mut table = CMD_PROCESS_TABLE . write ( ) . unwrap ( ) ;
80- for tuple in table. iter_mut ( ) {
81- let mut proc = tuple. 1 . lock ( ) . unwrap ( ) ;
82- match proc. try_wait ( ) {
83- // 正常运行
84- Ok ( None ) => { }
85- // 停止运行,从表中删除数据
86- _ => {
87- // TODO: 应该添加错误处理,有一些命令执行失败会影响服务正常运行
88- // 后续应该添加机制来执行服务相关命令启动失败的回调
89- exited. push ( * tuple. 0 ) ;
83+ if SIGCHILD_SIGNAL_RECEIVED
84+ . compare_exchange ( true , false , Ordering :: SeqCst , Ordering :: SeqCst )
85+ . is_ok ( )
86+ {
87+ let mut exited = Vec :: new ( ) ;
88+ let mut table = CMD_PROCESS_TABLE . write ( ) . unwrap ( ) ;
89+
90+ for tuple in table. iter_mut ( ) {
91+ let pid = Pid :: from_raw ( tuple. 1 . lock ( ) . unwrap ( ) . id ( ) as i32 ) ;
92+ match waitpid ( Some ( pid) , Some ( WaitPidFlag :: WNOHANG ) ) {
93+ // 若 cmd 停止运行,则将其加入退出列表
94+ Ok ( WaitStatus :: Exited ( _, _) ) | Ok ( WaitStatus :: Signaled ( _, _, _) ) => {
95+ eprintln ! ( "cmd exited" ) ;
96+ exited. push ( * tuple. 0 ) ;
97+ }
98+ Ok ( _) => { }
99+ Err ( _) => {
100+ // TODO: 应该添加错误处理,有一些命令执行失败会影响服务正常运行
101+ // 后续应该添加机制来执行服务相关命令启动失败的回调
102+ eprintln ! ( "cmd waitpid error" ) ;
103+ }
90104 }
91105 }
92- }
93106
94- for id in exited {
95- table. remove ( & id) ;
107+ for id in exited {
108+ table. remove ( & id) ;
109+ }
96110 }
97111 }
98112}
0 commit comments