1 use std::{collections::BTreeMap, env::Vars, rc::Rc, sync::RwLock}; 2 3 use log::{debug, info}; 4 5 use crate::{ 6 executor::cache::CacheDir, 7 scheduler::{SchedEntities, SchedEntity}, 8 }; 9 10 use self::cache::CacheDirType; 11 12 pub mod cache; 13 14 lazy_static! { 15 // 全局环境变量的列表 16 pub static ref ENV_LIST: RwLock<EnvMap> = RwLock::new(EnvMap::new()); 17 } 18 19 #[derive(Debug)] 20 pub struct Executor { 21 entity: Rc<SchedEntity>, 22 local_envs: EnvMap, 23 build_dir: CacheDir, 24 source_dir: Option<CacheDir>, 25 } 26 27 impl Executor { 28 /// # 创建执行器 29 /// 30 /// 用于执行一个任务 31 /// 32 /// ## 参数 33 /// 34 /// * `entity` - 任务调度实体 35 /// 36 /// ## 返回值 37 /// 38 /// * `Ok(Executor)` - 创建成功 39 /// * `Err(ExecutorError)` - 创建失败 40 pub fn new(entity: Rc<SchedEntity>) -> Result<Self, ExecutorError> { 41 let local_envs = EnvMap::new(); 42 let build_dir = CacheDir::new(entity.clone(), CacheDirType::Build)?; 43 44 let source_dir = if CacheDir::need_source_cache(&entity) { 45 Some(CacheDir::new(entity.clone(), CacheDirType::Source)?) 46 } else { 47 None 48 }; 49 50 let result: Executor = Self { 51 entity, 52 local_envs, 53 build_dir, 54 source_dir, 55 }; 56 57 return Ok(result); 58 } 59 60 /// # 执行任务 61 /// 62 /// 创建执行器后,调用此方法执行任务。 63 /// 该方法会执行以下步骤: 64 /// 65 /// 1. 创建工作线程 66 /// 2. 准备环境变量 67 /// 3. 拉取数据(可选) 68 /// 4. 执行构建 69 pub fn execute(&self) -> Result<(), ExecutorError> { 70 // todo!("Execute task: {:?}", self.entity.task()); 71 info!("Execute task: {}", self.entity.task().name_version()); 72 73 return Ok(()); 74 } 75 } 76 77 #[derive(Debug)] 78 pub struct EnvMap { 79 pub envs: BTreeMap<String, EnvVar>, 80 } 81 82 impl EnvMap { 83 pub fn new() -> Self { 84 Self { 85 envs: BTreeMap::new(), 86 } 87 } 88 89 pub fn add(&mut self, env: EnvVar) { 90 self.envs.insert(env.key.clone(), env); 91 } 92 93 pub fn get(&self, key: &str) -> Option<&EnvVar> { 94 self.envs.get(key) 95 } 96 97 pub fn add_vars(&mut self, vars: Vars) { 98 for (key, value) in vars { 99 self.add(EnvVar::new(key, value)); 100 } 101 } 102 } 103 104 #[derive(Debug, PartialEq, PartialOrd, Eq, Ord)] 105 pub struct EnvVar { 106 pub key: String, 107 pub value: String, 108 } 109 110 impl EnvVar { 111 pub fn new(key: String, value: String) -> Self { 112 Self { key, value } 113 } 114 } 115 116 #[derive(Debug)] 117 pub enum ExecutorError { 118 /// # 准备环境变量错误 119 PrepareEnvError, 120 IoError(std::io::Error), 121 } 122 123 pub fn prepare_env(sched_entities: &SchedEntities) -> Result<(), ExecutorError> { 124 info!("Preparing environment variables..."); 125 // 获取当前全局环境变量列表 126 let mut env_list = ENV_LIST.write().unwrap(); 127 let envs: Vars = std::env::vars(); 128 env_list.add_vars(envs); 129 130 // 为每个任务创建特定的环境变量 131 for entity in sched_entities.iter() { 132 // 导出任务的构建目录环境变量 133 let build_dir = CacheDir::build_dir(entity.clone())?; 134 135 let build_dir_key = CacheDir::build_dir_env_key(entity.clone())?; 136 env_list.add(EnvVar::new( 137 build_dir_key, 138 build_dir.to_str().unwrap().to_string(), 139 )); 140 141 // 如果需要源码缓存目录,则导出 142 if CacheDir::need_source_cache(entity) { 143 let source_dir = CacheDir::source_dir(entity.clone())?; 144 let source_dir_key = CacheDir::source_dir_env_key(entity.clone())?; 145 env_list.add(EnvVar::new( 146 source_dir_key, 147 source_dir.to_str().unwrap().to_string(), 148 )); 149 } 150 } 151 152 // 查看环境变量列表 153 // debug!("Environment variables:"); 154 155 // for (key, value) in env_list.envs.iter() { 156 // debug!("{}: {}", key, value.value); 157 // } 158 159 return Ok(()); 160 } 161