From d347f2db77d3643b8b1845b68f4f6b9170475811 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 25 Jul 2024 09:28:08 -0700 Subject: [PATCH] Log when plugin runtime exits --- .../tauri-plugin-plugin-runtime/src/lib.rs | 2 +- .../src/manager.rs | 19 ++++------ .../tauri-plugin-plugin-runtime/src/nodejs.rs | 36 +++++++++++++++---- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src-tauri/tauri-plugin-plugin-runtime/src/lib.rs b/src-tauri/tauri-plugin-plugin-runtime/src/lib.rs index 74ecc1a1..1d922e89 100644 --- a/src-tauri/tauri-plugin-plugin-runtime/src/lib.rs +++ b/src-tauri/tauri-plugin-plugin-runtime/src/lib.rs @@ -26,7 +26,7 @@ pub fn init() -> TauriPlugin { .on_event(|app, e| match e { RunEvent::ExitRequested { code, .. } => { tauri::async_runtime::block_on(async move { - info!("Exiting plugin runtime because of app exit {:?}", code); + info!("Exiting plugin runtime due to app exit {:?}", code); let manager: State> = app.state(); manager.lock().await.cleanup(); }); diff --git a/src-tauri/tauri-plugin-plugin-runtime/src/manager.rs b/src-tauri/tauri-plugin-plugin-runtime/src/manager.rs index 0344fb35..4825b3c2 100644 --- a/src-tauri/tauri-plugin-plugin-runtime/src/manager.rs +++ b/src-tauri/tauri-plugin-plugin-runtime/src/manager.rs @@ -1,6 +1,6 @@ -use command_group::GroupChild; use log::{debug, info}; use tauri::{AppHandle, Manager, Runtime}; +use tokio::sync::watch::Sender; use tonic::transport::Channel; use crate::nodejs::node_start; @@ -11,32 +11,27 @@ use crate::plugin_runtime::{ pub struct PluginManager { client: PluginRuntimeClient, - child: GroupChild, + kill_tx: Sender, } impl PluginManager { pub async fn new(app_handle: &AppHandle) -> PluginManager { let temp_dir = app_handle.path().temp_dir().unwrap(); - let start_resp = node_start(app_handle, &temp_dir).await; + let (kill_tx, kill_rx) = tokio::sync::watch::channel(false); + let start_resp = node_start(app_handle, &temp_dir, &kill_rx).await; info!("Connecting to gRPC client at {}", start_resp.addr); let client = match PluginRuntimeClient::connect(start_resp.addr.clone()).await { Ok(v) => v, - Err(err) => { - panic!("{}", err.to_string()); - } + Err(err) => panic!("{}", err.to_string()), }; - PluginManager { - client, - child: start_resp.child, - } + PluginManager { client, kill_tx } } pub fn cleanup(&mut self) { - info!("Cleaning up NodeJS process"); - self.child.kill().unwrap(); + self.kill_tx.send_replace(true); } pub async fn run_import(&mut self, data: &str) -> Result { diff --git a/src-tauri/tauri-plugin-plugin-runtime/src/nodejs.rs b/src-tauri/tauri-plugin-plugin-runtime/src/nodejs.rs index c40a921b..68ddcaa4 100644 --- a/src-tauri/tauri-plugin-plugin-runtime/src/nodejs.rs +++ b/src-tauri/tauri-plugin-plugin-runtime/src/nodejs.rs @@ -2,8 +2,8 @@ use std::path::PathBuf; use std::process::Command; use std::time::Duration; -use command_group::{CommandGroup, GroupChild}; -use log::{debug, info}; +use command_group::CommandGroup; +use log::{debug, error, info}; use rand::distributions::{Alphanumeric, DistString}; use serde; use serde::Deserialize; @@ -11,6 +11,7 @@ use tauri::path::BaseDirectory; use tauri::{AppHandle, Manager, Runtime}; use tauri_plugin_shell::ShellExt; use tokio::fs; +use tokio::sync::watch::Receiver; #[derive(Deserialize, Default)] #[serde(default, rename_all = "camelCase")] @@ -20,10 +21,13 @@ struct PortFile { pub struct StartResp { pub addr: String, - pub child: GroupChild, } -pub async fn node_start(app: &AppHandle, temp_dir: &PathBuf) -> StartResp { +pub async fn node_start( + app: &AppHandle, + temp_dir: &PathBuf, + kill_rx: &Receiver, +) -> StartResp { let port_file_path = temp_dir.join(Alphanumeric.sample_string(&mut rand::thread_rng(), 10)); let plugins_dir = app @@ -47,7 +51,7 @@ pub async fn node_start(app: &AppHandle, temp_dir: &PathBuf) -> S .to_string(); info!( - "Starting plugin runtime\n port_file={}\n plugins_dir={}\n runtime_dir={}", + "Starting plugin runtime\n → port_file={}\n → plugins_dir={}\n → runtime_dir={}", port_file_path.to_string_lossy(), plugins_dir, plugin_runtime_main, @@ -61,10 +65,28 @@ pub async fn node_start(app: &AppHandle, temp_dir: &PathBuf) -> S .env("YAAK_PLUGINS_DIR", plugins_dir) .args(&[plugin_runtime_main]); - let child = Command::from(cmd) + println!("Waiting on plugin runtime"); + let mut child = Command::from(cmd) .group_spawn() .expect("yaaknode failed to start"); + let kill_rx = kill_rx.clone(); + + // Check on child + tokio::spawn(async move { + loop { + if let Ok(Some(status)) = child.try_wait() { + error!("Plugin runtime exited status={}", status); + // TODO: Try restarting plugin runtime + break; + } else if *kill_rx.borrow() { + info!("Stopping plugin runtime"); + child.kill().expect("Failed to kill plugin runtime"); + break; + } + } + }); + let start = std::time::Instant::now(); let port_file_contents = loop { if start.elapsed().as_millis() > 30000 { @@ -84,5 +106,5 @@ pub async fn node_start(app: &AppHandle, temp_dir: &PathBuf) -> S info!("Started plugin runtime on :{}", port_file.port); let addr = format!("http://localhost:{}", port_file.port); - StartResp { addr, child } + StartResp { addr } }