| 38 | |
| 39 | impl SubProcess { |
| 40 | pub fn new( |
| 41 | command: PathBuf, |
| 42 | args: Vec<String>, |
| 43 | chdir: Option<PathBuf>, |
| 44 | envs: HashMap<String, String>, |
| 45 | result_tx: mpsc::Sender<Message>, |
| 46 | port: u16, |
| 47 | ) -> Self { |
| 48 | let canceled = Arc::new(AtomicBool::new(false)); |
| 49 | let (shutdown_tx, mut shutdown_rx) = mpsc::channel(1); |
| 50 | let command2 = command.clone(); |
| 51 | let args2 = args.clone(); |
| 52 | let canceled2 = canceled.clone(); |
| 53 | let result = Arc::new(RwLock::new(Ok(()))); |
| 54 | let result_clone = result.clone(); |
| 55 | tokio::spawn(async move { |
| 56 | if let Err(err) = execute(command2, args2, chdir, envs, None, &mut shutdown_rx).await { |
| 57 | if !canceled2.load(Ordering::Relaxed) { |
| 58 | error!("Failed to execute command: {:?}", err); |
| 59 | result_tx |
| 60 | .send(Message::Error(ErrorInfo { |
| 61 | kind: ErrorKind::ExecuteFailed.into(), |
| 62 | message: crate::t!("error-execute-failed", "err" => err.to_string()), |
| 63 | guid: String::new(), |
| 64 | })) |
| 65 | .await |
| 66 | .ok(); |
| 67 | } |
| 68 | *result_clone.write() = Err(err); |
| 69 | } |
| 70 | }); |
| 71 | Self { |
| 72 | shutdown_tx, |
| 73 | port, |
| 74 | command, |
| 75 | args, |
| 76 | canceled, |
| 77 | result, |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | pub fn stop(&mut self) { |
| 82 | self.canceled.store(true, Ordering::Relaxed); |