fix(process_manager): await child exit and reap process handles (v0.1.16) #77
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "iccery",
|
||||
"private": true,
|
||||
"version": "0.1.15",
|
||||
"version": "0.1.16",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"tauri": "tauri"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "iccery"
|
||||
version = "0.1.15"
|
||||
version = "0.1.16"
|
||||
description = "Modern Printer Profiling UI frontend for ArgyllCMS"
|
||||
authors = ["Gordon"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
use std::collections::HashMap;
|
||||
use std::process::Stdio;
|
||||
use std::sync::Arc;
|
||||
use tauri::AppHandle;
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||
use tokio::process::{Child, Command};
|
||||
use tokio::sync::Mutex;
|
||||
use tauri::AppHandle;
|
||||
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
use crate::events::{emit_error, emit_stderr, emit_stdout};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct ProcessManager {
|
||||
processes: Mutex<HashMap<String, Arc<Mutex<Child>>>>,
|
||||
processes: Arc<Mutex<HashMap<String, Arc<Mutex<Child>>>>>,
|
||||
}
|
||||
|
||||
impl ProcessManager {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
processes: Mutex::new(HashMap::new()),
|
||||
processes: Arc::new(Mutex::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn spawn(&self, app: AppHandle, id: String, binary: String, args: Vec<String>, cwd: Option<String>) -> Result<(), String> {
|
||||
pub async fn spawn(
|
||||
&self,
|
||||
app: AppHandle,
|
||||
id: String,
|
||||
binary: String,
|
||||
args: Vec<String>,
|
||||
cwd: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
let mut command = Command::new(&binary);
|
||||
command.args(args);
|
||||
if let Some(dir) = cwd {
|
||||
@@ -69,20 +72,30 @@ impl ProcessManager {
|
||||
});
|
||||
|
||||
let child_arc = Arc::new(Mutex::new(child));
|
||||
let mut processes = self.processes.lock().await;
|
||||
processes.insert(id.clone(), child_arc.clone());
|
||||
{
|
||||
let mut processes = self.processes.lock().await;
|
||||
processes.insert(id.clone(), child_arc.clone());
|
||||
}
|
||||
|
||||
let id_clone_exit = id.clone();
|
||||
let app_clone_exit = app.clone();
|
||||
let processes_clone = self.processes.clone();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
let exit_code = {
|
||||
let mut c = child_arc.lock().await;
|
||||
if let Ok(Some(status)) = c.try_wait() {
|
||||
crate::events::emit_exit(&app_clone_exit, &id_clone_exit, status.code().unwrap_or(1));
|
||||
break;
|
||||
match c.wait().await {
|
||||
Ok(status) => status.code().unwrap_or(0),
|
||||
Err(_) => 1,
|
||||
}
|
||||
};
|
||||
|
||||
// Reap child from process manager map upon exit
|
||||
{
|
||||
let mut processes = processes_clone.lock().await;
|
||||
processes.remove(&id_clone_exit);
|
||||
}
|
||||
|
||||
crate::events::emit_exit(&app_clone_exit, &id_clone_exit, exit_code);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "ICCery",
|
||||
"version": "0.1.15",
|
||||
"version": "0.1.16",
|
||||
"identifier": "com.gronod.iccery",
|
||||
"build": {
|
||||
"frontendDist": "../src"
|
||||
|
||||
Reference in New Issue
Block a user