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