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 { running_table(&self) -> &HashMap<usize, Child>38 pub fn running_table(&self) -> &HashMap<usize, Child> { 39 &self.running_table 40 } 41 mut_running_table(&mut self) -> &mut HashMap<usize, Child>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的映射 insert_into_name_table(path: &str, unit: usize)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 contains_name(path: &str) -> bool62 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 get_unit_with_name(name: &str) -> Option<Arc<Mutex<dyn 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 get_unit_with_id(id: &usize) -> Option<Arc<Mutex<dyn 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 // ↑感觉是笔误,应该是通过path获取到id get_id_with_path(path: &str) -> Option<usize>96 pub fn get_id_with_path(path: &str) -> Option<usize> { 97 let mut hasher = DefaultHasher::new(); 98 path.hash(&mut hasher); 99 let hash = hasher.finish(); 100 NAME_TO_UNIT_MAP.read().unwrap().get(&hash).cloned() 101 } 102 103 // 判断该Unit是否正在运行中 is_running_unit(id: &usize) -> bool104 pub fn is_running_unit(id: &usize) -> bool { 105 RUNNING_TABLE.read().unwrap().running_table.contains_key(id) 106 || !FLAG_RUNNING 107 .read() 108 .unwrap() 109 .iter() 110 .filter(|x| **x == *id) 111 .collect::<Vec<_>>() 112 .is_empty() 113 } 114 115 // 向运行表中添加运行的Unit push_running(unit_id: usize, p: Child)116 pub fn push_running(unit_id: usize, p: Child) { 117 RUNNING_TABLE 118 .write() 119 .unwrap() 120 .running_table 121 .insert(unit_id, p); 122 } 123 124 // 删除运行表中的Unit remove_running(id: usize)125 pub fn remove_running(id: usize) { 126 let mut table = RUNNING_TABLE.write().unwrap(); 127 table.running_table.remove(&id); 128 } 129 130 // 向id到Unit映射表中插入数据 insert_unit_with_id(id: usize, unit: Arc<Mutex<dyn Unit>>)131 pub fn insert_unit_with_id(id: usize, unit: Arc<Mutex<dyn Unit>>) { 132 let mut map = ID_TO_UNIT_MAP.write().unwrap(); 133 if !map.contains_key(&id) { 134 map.insert(id, unit); 135 } 136 } 137 138 // 判断当前DragonReach是否拥有目标id的Unit contains_id(id: &usize) -> bool139 pub fn contains_id(id: &usize) -> bool { 140 ID_TO_UNIT_MAP.read().unwrap().contains_key(id) 141 } 142 143 // 弹出一个处于IDLE状态的Service pop_a_idle_service() -> Option<Arc<Mutex<dyn Unit>>>144 pub fn pop_a_idle_service() -> Option<Arc<Mutex<dyn Unit>>> { 145 let id = IDLE_SERVIEC_DEQUE.lock().unwrap().pop_front(); 146 match id { 147 Some(id) => { 148 return Self::get_unit_with_id(&id); 149 } 150 None => { 151 return None; 152 } 153 } 154 } 155 156 // 添加IDLE状态的Service,将在后续调度 push_a_idle_service(id: usize)157 pub fn push_a_idle_service(id: usize) { 158 if !Self::contains_id(&id) { 159 return; 160 } 161 IDLE_SERVIEC_DEQUE.lock().unwrap().push_back(id); 162 } 163 164 // 将该Unit标记为运行状态,并且后续不会对其进行运行检查 push_flag_running(id: usize)165 pub fn push_flag_running(id: usize) { 166 let mut t = FLAG_RUNNING.write().unwrap(); 167 if t.contains(&id) { 168 return; 169 } 170 t.push(id); 171 } 172 173 // 当前运行的Unit数 running_count() -> usize174 pub fn running_count() -> usize { 175 return RUNNING_TABLE.read().unwrap().running_table.len(); 176 } 177 178 // 向Cmd运行表中添加 push_cmd_proc(proc: Child)179 pub fn push_cmd_proc(proc: Child) { 180 CMD_PROCESS_TABLE 181 .write() 182 .unwrap() 183 .insert(proc.id(), Mutex::new(proc)); 184 } 185 186 // 弹出指定id的cmd进程 pop_cmd_proc(id: u32) -> Option<Mutex<Child>>187 pub fn pop_cmd_proc(id: u32) -> Option<Mutex<Child>> { 188 CMD_PROCESS_TABLE.write().unwrap().remove(&id) 189 } 190 191 // 初始化各Unit的依赖关系,此方法只需在解析完系统Unit文件后调用一次 init_units_dependencies()192 pub fn init_units_dependencies() { 193 let manager = ID_TO_UNIT_MAP.write().unwrap(); 194 195 // 处理before段,将before段的Unit添加此Unit为After 196 for (id, unit) in manager.iter() { 197 let mut unit = unit.lock().unwrap(); 198 let before = unit.unit_base_mut().unit_part().before(); 199 for rid in before { 200 let req = UnitManager::get_unit_with_id(rid).unwrap(); 201 let mut req = req.lock().unwrap(); 202 req.unit_base_mut().mut_unit_part().push_after_unit(*id); 203 } 204 } 205 206 for (id, unit) in manager.iter() { 207 let mut unit = unit.lock().unwrap(); 208 209 // 处理binds_to段 210 let binds_to = unit.unit_base_mut().unit_part().binds_to(); 211 for rid in binds_to { 212 let req = UnitManager::get_unit_with_id(rid).unwrap(); 213 let mut req = req.lock().unwrap(); 214 req.unit_base_mut().mut_unit_part().push_be_binded_by(*id); 215 } 216 217 // 处理part_of段 218 let part_of = unit.unit_base_mut().unit_part().part_of(); 219 for rid in part_of { 220 let req = UnitManager::get_unit_with_id(rid).unwrap(); 221 let mut req = req.lock().unwrap(); 222 req.unit_base_mut().mut_unit_part().push_be_binded_by(*id); 223 } 224 } 225 } 226 227 /// ## 如果Unit进程正在运行则杀死Unit进程 try_kill_running(id: usize) -> bool228 pub fn try_kill_running(id: usize) -> bool { 229 if Self::is_running_unit(&id) { 230 Self::kill_running(id); 231 return true; 232 } 233 return false; 234 } 235 kill_running(id: usize)236 pub fn kill_running(id: usize) { 237 let mut running_manager = RUNNING_TABLE.write().unwrap(); 238 let unit = running_manager.running_table.get_mut(&id).unwrap(); 239 let _ = unit.kill(); 240 println!("kill:{}", id); 241 running_manager.running_table.remove(&id); 242 } 243 } 244