mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-19 23:31:21 +02:00
Limit CLI plugin runtime startup and harden shutdown watcher
This commit is contained in:
@@ -161,7 +161,7 @@ pub async fn send_request_by_id(
|
|||||||
|
|
||||||
let plugin_context = PluginContext::new(None, Some(request.workspace_id.clone()));
|
let plugin_context = PluginContext::new(None, Some(request.workspace_id.clone()));
|
||||||
let template_callback = PluginTemplateCallback::new(
|
let template_callback = PluginTemplateCallback::new(
|
||||||
ctx.plugin_manager.clone(),
|
ctx.plugin_manager(),
|
||||||
ctx.encryption_manager.clone(),
|
ctx.encryption_manager.clone(),
|
||||||
&plugin_context,
|
&plugin_context,
|
||||||
RenderPurpose::Send,
|
RenderPurpose::Send,
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ use yaak_plugins::manager::PluginManager;
|
|||||||
pub struct CliContext {
|
pub struct CliContext {
|
||||||
query_manager: QueryManager,
|
query_manager: QueryManager,
|
||||||
pub encryption_manager: Arc<EncryptionManager>,
|
pub encryption_manager: Arc<EncryptionManager>,
|
||||||
pub plugin_manager: Arc<PluginManager>,
|
plugin_manager: Option<Arc<PluginManager>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CliContext {
|
impl CliContext {
|
||||||
pub async fn initialize(data_dir: PathBuf, app_id: &str) -> Self {
|
pub async fn initialize(data_dir: PathBuf, app_id: &str, with_plugins: bool) -> Self {
|
||||||
let db_path = data_dir.join("db.sqlite");
|
let db_path = data_dir.join("db.sqlite");
|
||||||
let blob_path = data_dir.join("blobs.sqlite");
|
let blob_path = data_dir.join("blobs.sqlite");
|
||||||
|
|
||||||
@@ -23,35 +23,45 @@ impl CliContext {
|
|||||||
|
|
||||||
let encryption_manager = Arc::new(EncryptionManager::new(query_manager.clone(), app_id));
|
let encryption_manager = Arc::new(EncryptionManager::new(query_manager.clone(), app_id));
|
||||||
|
|
||||||
let vendored_plugin_dir = data_dir.join("vendored-plugins");
|
let plugin_manager = if with_plugins {
|
||||||
let installed_plugin_dir = data_dir.join("installed-plugins");
|
let vendored_plugin_dir = data_dir.join("vendored-plugins");
|
||||||
let node_bin_path = PathBuf::from("node");
|
let installed_plugin_dir = data_dir.join("installed-plugins");
|
||||||
|
let node_bin_path = PathBuf::from("node");
|
||||||
|
|
||||||
let plugin_runtime_main =
|
let plugin_runtime_main =
|
||||||
std::env::var("YAAK_PLUGIN_RUNTIME").map(PathBuf::from).unwrap_or_else(|_| {
|
std::env::var("YAAK_PLUGIN_RUNTIME").map(PathBuf::from).unwrap_or_else(|_| {
|
||||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||||
.join("../../crates-tauri/yaak-app/vendored/plugin-runtime/index.cjs")
|
.join("../../crates-tauri/yaak-app/vendored/plugin-runtime/index.cjs")
|
||||||
});
|
});
|
||||||
|
|
||||||
let plugin_manager = Arc::new(
|
let plugin_manager = Arc::new(
|
||||||
PluginManager::new(
|
PluginManager::new(
|
||||||
vendored_plugin_dir,
|
vendored_plugin_dir,
|
||||||
installed_plugin_dir,
|
installed_plugin_dir,
|
||||||
node_bin_path,
|
node_bin_path,
|
||||||
plugin_runtime_main,
|
plugin_runtime_main,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
);
|
);
|
||||||
|
|
||||||
let plugins = query_manager.connect().list_plugins().unwrap_or_default();
|
let plugins = query_manager.connect().list_plugins().unwrap_or_default();
|
||||||
if !plugins.is_empty() {
|
if !plugins.is_empty() {
|
||||||
let errors =
|
let errors = plugin_manager
|
||||||
plugin_manager.initialize_all_plugins(plugins, &PluginContext::new_empty()).await;
|
.initialize_all_plugins(plugins, &PluginContext::new_empty())
|
||||||
for (plugin_dir, error_msg) in errors {
|
.await;
|
||||||
eprintln!("Warning: Failed to initialize plugin '{}': {}", plugin_dir, error_msg);
|
for (plugin_dir, error_msg) in errors {
|
||||||
|
eprintln!(
|
||||||
|
"Warning: Failed to initialize plugin '{}': {}",
|
||||||
|
plugin_dir, error_msg
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Some(plugin_manager)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
Self { query_manager, encryption_manager, plugin_manager }
|
Self { query_manager, encryption_manager, plugin_manager }
|
||||||
}
|
}
|
||||||
@@ -60,7 +70,13 @@ impl CliContext {
|
|||||||
self.query_manager.connect()
|
self.query_manager.connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn plugin_manager(&self) -> Arc<PluginManager> {
|
||||||
|
self.plugin_manager.clone().expect("Plugin manager was not initialized for this command")
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn shutdown(&self) {
|
pub async fn shutdown(&self) {
|
||||||
self.plugin_manager.terminate().await;
|
if let Some(plugin_manager) = &self.plugin_manager {
|
||||||
|
plugin_manager.terminate().await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ mod commands;
|
|||||||
mod context;
|
mod context;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use cli::{Cli, Commands};
|
use cli::{Cli, Commands, RequestCommands};
|
||||||
use context::CliContext;
|
use context::CliContext;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
@@ -20,7 +20,13 @@ async fn main() {
|
|||||||
dirs::data_dir().expect("Could not determine data directory").join(app_id)
|
dirs::data_dir().expect("Could not determine data directory").join(app_id)
|
||||||
});
|
});
|
||||||
|
|
||||||
let context = CliContext::initialize(data_dir, app_id).await;
|
let needs_plugins = matches!(
|
||||||
|
&command,
|
||||||
|
Commands::Send(_)
|
||||||
|
| Commands::Request(cli::RequestArgs { command: RequestCommands::Send { .. } })
|
||||||
|
);
|
||||||
|
|
||||||
|
let context = CliContext::initialize(data_dir, app_id, needs_plugins).await;
|
||||||
|
|
||||||
let exit_code = match command {
|
let exit_code = match command {
|
||||||
Commands::Send(args) => {
|
Commands::Send(args) => {
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ pub async fn start_nodejs_plugin_runtime(
|
|||||||
// Handle kill signal
|
// Handle kill signal
|
||||||
let mut kill_rx = kill_rx.clone();
|
let mut kill_rx = kill_rx.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
kill_rx.wait_for(|b| *b == true).await.expect("Kill channel errored");
|
if kill_rx.wait_for(|b| *b == true).await.is_err() {
|
||||||
|
warn!("Kill channel closed before explicit shutdown; terminating plugin runtime");
|
||||||
|
}
|
||||||
info!("Killing plugin runtime");
|
info!("Killing plugin runtime");
|
||||||
if let Err(e) = child.kill().await {
|
if let Err(e) = child.kill().await {
|
||||||
warn!("Failed to kill plugin runtime: {e}");
|
warn!("Failed to kill plugin runtime: {e}");
|
||||||
|
|||||||
Reference in New Issue
Block a user