aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-server/src/plugins/plugin_worker.rs
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2023-06-07 12:43:35 +0200
committerGitHub <noreply@github.com>2023-06-07 12:43:35 +0200
commitc11d75f9157873fc99fe0d40933de8ec5fbb4f6b (patch)
treefc55dc7f9132395585613dd9cce94c98c8c76600 /zellij-server/src/plugins/plugin_worker.rs
parentdocs(changelog): fix cwd of newtab action (diff)
downloadsl0ppij-c11d75f9157873fc99fe0d40933de8ec5fbb4f6b.tar.gz
sl0ppij-c11d75f9157873fc99fe0d40933de8ec5fbb4f6b.tar.xz
sl0ppij-c11d75f9157873fc99fe0d40933de8ec5fbb4f6b.zip
feat(wasm-plugin-system): major overhaul and some goodies (#2510)
* strider resiliency * worker channel prototype * finalized ui * show hide plugin * fs events to plugins * tests for events and new screen instructions * various refactoringz * report plugin errors instead of crashing zellij * fix plugin loading with workers * refactor: move watch filesystem * some fixes and refactoring * refactor(panes): combine pane insertion logic * refactor(screen): launch or focus * refactor(pty): consolidate default shell fetching * refactor: various cleanups * initial refactoring * more initial refactoring * refactor(strider): search * style(fmt): rustfmt * style(pty): cleanup * style(clippy): ok clippy * style(fmt): rustfmt
Diffstat (limited to 'zellij-server/src/plugins/plugin_worker.rs')
-rw-r--r--zellij-server/src/plugins/plugin_worker.rs89
1 files changed, 89 insertions, 0 deletions
diff --git a/zellij-server/src/plugins/plugin_worker.rs b/zellij-server/src/plugins/plugin_worker.rs
new file mode 100644
index 00000000..bc7303c7
--- /dev/null
+++ b/zellij-server/src/plugins/plugin_worker.rs
@@ -0,0 +1,89 @@
+use crate::plugins::plugin_loader::VersionMismatchError;
+use crate::plugins::plugin_map::PluginEnv;
+use crate::plugins::zellij_exports::wasi_write_object;
+use wasmer::Instance;
+
+use zellij_utils::async_channel::{unbounded, Receiver, Sender};
+use zellij_utils::async_std::task;
+use zellij_utils::errors::prelude::*;
+use zellij_utils::{consts::VERSION, input::plugins::PluginConfig};
+
+pub struct RunningWorker {
+ pub instance: Instance,
+ pub name: String,
+ pub plugin_config: PluginConfig,
+ pub plugin_env: PluginEnv,
+}
+
+impl RunningWorker {
+ pub fn new(
+ instance: Instance,
+ name: &str,
+ plugin_config: PluginConfig,
+ plugin_env: PluginEnv,
+ ) -> Self {
+ RunningWorker {
+ instance,
+ name: name.into(),
+ plugin_config,
+ plugin_env,
+ }
+ }
+ pub fn send_message(&self, message: String, payload: String) -> Result<()> {
+ let err_context = || format!("Failed to send message to worker");
+
+ let work_function = self
+ .instance
+ .exports
+ .get_function(&self.name)
+ .with_context(err_context)?;
+ wasi_write_object(&self.plugin_env.wasi_env, &(message, payload))
+ .with_context(err_context)?;
+ work_function.call(&[]).or_else::<anyError, _>(|e| {
+ match e.downcast::<serde_json::Error>() {
+ Ok(_) => panic!(
+ "{}",
+ anyError::new(VersionMismatchError::new(
+ VERSION,
+ "Unavailable",
+ &self.plugin_config.path,
+ self.plugin_config.is_builtin(),
+ ))
+ ),
+ Err(e) => Err(e).with_context(err_context),
+ }
+ })?;
+
+ Ok(())
+ }
+}
+
+pub enum MessageToWorker {
+ Message(String, String), // message, payload
+ Exit,
+}
+
+pub fn plugin_worker(worker: RunningWorker) -> Sender<MessageToWorker> {
+ let (sender, receiver): (Sender<MessageToWorker>, Receiver<MessageToWorker>) = unbounded();
+ task::spawn({
+ async move {
+ loop {
+ match receiver.recv().await {
+ Ok(MessageToWorker::Message(message, payload)) => {
+ if let Err(e) = worker.send_message(message, payload) {
+ log::error!("Failed to send message to worker: {:?}", e);
+ }
+ },
+ Ok(MessageToWorker::Exit) => {
+ break;
+ },
+ Err(e) => {
+ log::error!("Failed to receive worker message on channel: {:?}", e);
+ break;
+ },
+ }
+ }
+ }
+ });
+ sender
+}