diff options
| author | Aram Drevekenin <aram@poor.dev> | 2023-06-07 12:43:35 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-07 12:43:35 +0200 |
| commit | c11d75f9157873fc99fe0d40933de8ec5fbb4f6b (patch) | |
| tree | fc55dc7f9132395585613dd9cce94c98c8c76600 /zellij-server/src/plugins/plugin_worker.rs | |
| parent | docs(changelog): fix cwd of newtab action (diff) | |
| download | sl0ppij-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.rs | 89 |
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 +} |
