xref: /DADK/src/executor/mod.rs (revision 8c888a14fe18483d70ffc05a82a0aa923ac2e5ec)
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