1 use std::{ 2 collections::{hash_map::DefaultHasher, VecDeque}, 3 hash::{Hash, Hasher}, 4 process::Child, 5 sync::{Arc, Mutex, RwLock}, 6 }; 7 8 use crate::unit::Unit; 9 use hashbrown::HashMap; 10 use lazy_static::lazy_static; 11 12 lazy_static! { 13 // 对于启动后即使退出亦认为其为运行状态的特殊注册类Service,对于这类进程做一个标记 14 static ref FLAG_RUNNING: RwLock<Vec<usize>> = RwLock::new(Vec::new()); 15 16 // 任务等待队列,IDLE类型的service入队等待其它任务完成再执行 17 static ref IDLE_SERVIEC_DEQUE: Mutex<VecDeque<usize>> = Mutex::new(VecDeque::new()); 18 19 // id到unit的映射表,全局的Unit管理表 20 pub(super) static ref ID_TO_UNIT_MAP: RwLock<HashMap<usize,Arc<Mutex<dyn Unit>>>> = RwLock::new(HashMap::new()); 21 22 // 辅助表,通过服务名映射其id 23 static ref NAME_TO_UNIT_MAP: RwLock<HashMap<u64,usize>> = RwLock::new(HashMap::new()); 24 25 // 全局运行中的Unit表 26 pub(super) static ref RUNNING_TABLE: RwLock<RunningTableManager> = RwLock::new(RunningTableManager { running_table: HashMap::new() }); 27 28 // CMD进程表,用于处理Unit的CMD派生进程(ExecStartPre等命令派生进程) 29 pub(super) static ref CMD_PROCESS_TABLE: RwLock<HashMap<u32,Mutex<Child>>> = RwLock::new(HashMap::new()); 30 } 31 32 pub struct RunningTableManager { 33 running_table: HashMap<usize, Child>, 34 } 35 36 #[allow(dead_code)] 37 impl RunningTableManager { 38 pub fn running_table(&self) -> &HashMap<usize, Child> { 39 &self.running_table 40 } 41 42 pub fn mut_running_table(&mut self) -> &mut HashMap<usize, Child> { 43 &mut self.running_table 44 } 45 } 46 47 pub struct UnitManager; 48 49 unsafe impl Sync for UnitManager {} 50 51 #[allow(dead_code)] 52 impl UnitManager { 53 /// 插入一条path到unit_id的映射 54 pub fn insert_into_name_table(path: &str, unit: usize) { 55 let mut hasher = DefaultHasher::new(); 56 path.hash(&mut hasher); 57 let hash = hasher.finish(); 58 NAME_TO_UNIT_MAP.write().unwrap().insert(hash, unit); 59 } 60 61 // 判断当前是否已经有了对应path的Unit 62 pub fn contains_name(path: &str) -> bool { 63 let mut hasher = DefaultHasher::new(); 64 path.hash(&mut hasher); 65 let hash = hasher.finish(); 66 NAME_TO_UNIT_MAP.read().unwrap().contains_key(&hash) 67 } 68 69 // 通过path获取到Unit 70 pub fn get_unit_with_name(name: &str) -> Option<Arc<Mutex<dyn Unit>>> { 71 let mut hasher = DefaultHasher::new(); 72 name.hash(&mut hasher); 73 let hash = hasher.finish(); 74 let map = NAME_TO_UNIT_MAP.read().unwrap(); 75 let id = match map.get(&hash) { 76 Some(id) => id, 77 None => { 78 return None; 79 } 80 }; 81 82 let map = ID_TO_UNIT_MAP.read().unwrap(); 83 let ret = map.get(id).cloned(); 84 ret 85 } 86 87 // 通过unit_id获取Unit 88 pub fn get_unit_with_id(id: &usize) -> Option<Arc<Mutex<dyn Unit>>> { 89 let map = ID_TO_UNIT_MAP.read().unwrap(); 90 let ret = map.get(&id).cloned(); 91 ret 92 } 93 94 // 通过id获取到path 95 pub fn get_id_with_path(path: &str) -> Option<usize> { 96 let mut hasher = DefaultHasher::new(); 97 path.hash(&mut hasher); 98 let hash = hasher.finish(); 99 NAME_TO_UNIT_MAP.read().unwrap().get(&hash).cloned() 100 } 101 102 // 判断该Unit是否正在运行中 103 pub fn is_running_unit(id: &usize) -> bool { 104 RUNNING_TABLE.read().unwrap().running_table.contains_key(id) 105 || !FLAG_RUNNING 106 .read() 107 .unwrap() 108 .iter() 109 .filter(|x| **x == *id) 110 .collect::<Vec<_>>() 111 .is_empty() 112 } 113 114 // 向运行表中添加运行的Unit 115 pub fn push_running(unit_id: usize, p: Child) { 116 RUNNING_TABLE 117 .write() 118 .unwrap() 119 .running_table 120 .insert(unit_id, p); 121 } 122 123 // 删除运行表中的Unit 124 pub fn remove_running(id: usize) { 125 let mut table = RUNNING_TABLE.write().unwrap(); 126 table.running_table.remove(&id); 127 } 128 129 // 向id到Unit映射表中插入数据 130 pub fn insert_unit_with_id(id: usize, unit: Arc<Mutex<dyn Unit>>) { 131 let mut map = ID_TO_UNIT_MAP.write().unwrap(); 132 if !map.contains_key(&id) { 133 map.insert(id, unit); 134 } 135 } 136 137 // 判断当前DragonReach是否拥有目标id的Unit 138 pub fn contains_id(id: &usize) -> bool { 139 ID_TO_UNIT_MAP.read().unwrap().contains_key(id) 140 } 141 142 // 弹出一个处于IDLE状态的Service 143 pub fn pop_a_idle_service() -> Option<Arc<Mutex<dyn Unit>>> { 144 let id = IDLE_SERVIEC_DEQUE.lock().unwrap().pop_front(); 145 match id { 146 Some(id) => { 147 return Self::get_unit_with_id(&id); 148 } 149 None => { 150 return None; 151 } 152 } 153 } 154 155 // 添加IDLE状态的Service,将在后续调度 156 pub fn push_a_idle_service(id: usize) { 157 if !Self::contains_id(&id) { 158 return; 159 } 160 IDLE_SERVIEC_DEQUE.lock().unwrap().push_back(id); 161 } 162 163 // 将该Unit标记为运行状态,并且后续不会对其进行运行检查 164 pub fn push_flag_running(id: usize) { 165 let mut t = FLAG_RUNNING.write().unwrap(); 166 if t.contains(&id) { 167 return; 168 } 169 t.push(id); 170 } 171 172 // 当前运行的Unit数 173 pub fn running_count() -> usize { 174 return RUNNING_TABLE.read().unwrap().running_table.len(); 175 } 176 177 // 向Cmd运行表中添加 178 pub fn push_cmd_proc(proc: Child) { 179 CMD_PROCESS_TABLE 180 .write() 181 .unwrap() 182 .insert(proc.id(), Mutex::new(proc)); 183 } 184 185 // 弹出指定id的cmd进程 186 pub fn pop_cmd_proc(id: u32) -> Option<Mutex<Child>> { 187 CMD_PROCESS_TABLE.write().unwrap().remove(&id) 188 } 189 190 // 初始化各Unit的依赖关系,此方法只需在解析完系统Unit文件后调用一次 191 pub fn init_units_dependencies() { 192 let manager = ID_TO_UNIT_MAP.write().unwrap(); 193 194 // 处理before段,将before段的Unit添加此Unit为After 195 for (id, unit) in manager.iter() { 196 let mut unit = unit.lock().unwrap(); 197 let before = unit.unit_base_mut().unit_part().before(); 198 for rid in before { 199 let req = UnitManager::get_unit_with_id(rid).unwrap(); 200 let mut req = req.lock().unwrap(); 201 req.unit_base_mut().mut_unit_part().push_after_unit(*id); 202 } 203 } 204 205 for (id, unit) in manager.iter() { 206 let mut unit = unit.lock().unwrap(); 207 208 // 处理binds_to段 209 let binds_to = unit.unit_base_mut().unit_part().binds_to(); 210 for rid in binds_to { 211 let req = UnitManager::get_unit_with_id(rid).unwrap(); 212 let mut req = req.lock().unwrap(); 213 req.unit_base_mut().mut_unit_part().push_be_binded_by(*id); 214 } 215 216 // 处理part_of段 217 let part_of = unit.unit_base_mut().unit_part().part_of(); 218 for rid in part_of { 219 let req = UnitManager::get_unit_with_id(rid).unwrap(); 220 let mut req = req.lock().unwrap(); 221 req.unit_base_mut().mut_unit_part().push_be_binded_by(*id); 222 } 223 } 224 } 225 226 /// ## 如果Unit进程正在运行则杀死Unit进程 227 pub fn try_kill_running(id: usize) -> bool { 228 if Self::is_running_unit(&id) { 229 Self::kill_running(id); 230 return true; 231 } 232 return false; 233 } 234 235 pub fn kill_running(id: usize) { 236 let mut running_manager = RUNNING_TABLE.write().unwrap(); 237 let unit = running_manager.running_table.get_mut(&id).unwrap(); 238 let _ = unit.kill(); 239 println!("kill:{}", id); 240 running_manager.running_table.remove(&id); 241 } 242 } 243