mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-22 17:39:12 +01:00
Plugin init/dispose
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use tauri::{Runtime, WebviewWindow};
|
||||
use ts_rs::TS;
|
||||
@@ -64,10 +65,9 @@ impl PluginWindowContext {
|
||||
#[ts(export, export_to = "gen_events.ts")]
|
||||
pub enum InternalEventPayload {
|
||||
BootRequest(BootRequest),
|
||||
BootResponse(BootResponse),
|
||||
BootResponse,
|
||||
|
||||
ReloadRequest(EmptyPayload),
|
||||
ReloadResponse(BootResponse),
|
||||
ReloadResponse(ReloadResponse),
|
||||
|
||||
TerminateRequest,
|
||||
TerminateResponse,
|
||||
@@ -161,6 +161,17 @@ pub enum InternalEventPayload {
|
||||
ErrorResponse(ErrorResponse),
|
||||
}
|
||||
|
||||
impl InternalEventPayload {
|
||||
pub fn type_name(&self) -> String {
|
||||
if let Ok(Value::Object(map)) = serde_json::to_value(self) {
|
||||
map.get("type").map(|s| s.as_str().unwrap_or("unknown").to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
.unwrap_or("invalid_event".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default)]
|
||||
#[ts(export, type = "{}", export_to = "gen_events.ts")]
|
||||
@@ -184,9 +195,8 @@ pub struct BootRequest {
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "gen_events.ts")]
|
||||
pub struct BootResponse {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub struct ReloadResponse {
|
||||
pub silent: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::nodejs::start_nodejs_plugin_runtime;
|
||||
use crate::plugin_handle::PluginHandle;
|
||||
use crate::server_ws::PluginRuntimeServerWebsocket;
|
||||
use crate::template_callback::PluginTemplateCallback;
|
||||
use log::{error, info, warn};
|
||||
use log::{debug, error, info, warn};
|
||||
use serde_json::json;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
@@ -31,6 +31,7 @@ use tauri::{AppHandle, Manager, Runtime, WebviewWindow, is_dev};
|
||||
use tokio::fs::read_dir;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::sync::{Mutex, mpsc};
|
||||
use tokio::sync::mpsc::error::TrySendError;
|
||||
use tokio::time::{Instant, timeout};
|
||||
use yaak_models::models::Environment;
|
||||
use yaak_models::query_manager::QueryManagerExt;
|
||||
@@ -91,7 +92,14 @@ impl PluginManager {
|
||||
while let Some(event) = events_rx.recv().await {
|
||||
for (tx_id, tx) in subscribers.lock().await.iter_mut() {
|
||||
if let Err(e) = tx.try_send(event.clone()) {
|
||||
warn!("Failed to send event to subscriber {tx_id} {e:?}");
|
||||
match e {
|
||||
TrySendError::Full(e) => {
|
||||
error!("Failed to send event to full subscriber {tx_id} {e:?}");
|
||||
}
|
||||
TrySendError::Closed(_) => {
|
||||
// Subscriber already unsubscribed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,17 +248,14 @@ impl PluginManager {
|
||||
)
|
||||
.await??;
|
||||
|
||||
let mut plugins = self.plugins.lock().await;
|
||||
if !matches!(event.payload, InternalEventPayload::BootResponse) {
|
||||
return Err(UnknownEventErr);
|
||||
}
|
||||
|
||||
// Remove the existing plugin (if exists) before adding this one
|
||||
let mut plugins = self.plugins.lock().await;
|
||||
plugins.retain(|p| p.dir != dir);
|
||||
plugins.push(plugin_handle.clone());
|
||||
|
||||
let _ = match event.payload {
|
||||
InternalEventPayload::BootResponse(resp) => resp,
|
||||
_ => return Err(UnknownEventErr),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -363,7 +368,7 @@ impl PluginManager {
|
||||
payload: &InternalEventPayload,
|
||||
plugins: Vec<PluginHandle>,
|
||||
) -> Result<Vec<InternalEvent>> {
|
||||
let label = format!("wait[{}]", plugins.len());
|
||||
let label = format!("wait[{}.{}]", plugins.len(), payload.type_name());
|
||||
let (rx_id, mut rx) = self.subscribe(label.as_str()).await;
|
||||
|
||||
// 1. Build the events with IDs and everything
|
||||
@@ -411,7 +416,7 @@ impl PluginManager {
|
||||
let events = sub_events_fut.await.expect("Thread didn't succeed");
|
||||
|
||||
// 5. Unsubscribe
|
||||
self.unsubscribe(rx_id.as_str()).await;
|
||||
self.unsubscribe(&rx_id).await;
|
||||
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ use crate::error::Result;
|
||||
use crate::events::{InternalEvent, InternalEventPayload, PluginWindowContext};
|
||||
use crate::plugin_meta::{PluginMetadata, get_plugin_meta};
|
||||
use crate::util::gen_id;
|
||||
use log::info;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{Mutex, mpsc};
|
||||
@@ -58,13 +57,6 @@ impl PluginHandle {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn terminate(&self, window_context: &PluginWindowContext) -> Result<()> {
|
||||
info!("Terminating plugin {}", self.dir);
|
||||
let event =
|
||||
self.build_event_to_send(window_context, &InternalEventPayload::TerminateRequest, None);
|
||||
self.send(&event).await
|
||||
}
|
||||
|
||||
pub async fn send(&self, event: &InternalEvent) -> Result<()> {
|
||||
self.to_plugin_tx.lock().await.send(event.to_owned()).await?;
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user