fix(plugins): only listen to hd if a plugin is subscribed to hd events (#2529)

* fix(plugins): only listen to hd if a plugin is subscribed to hd events

* style(fmt): rustfmt

* fix(tests): give time for fs watcher to do its thing

* fix(tests): increase timeout
This commit is contained in:
Aram Drevekenin 2023-06-13 08:59:44 +02:00 committed by GitHub
parent 9e69bea434
commit 0b831cfee5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 20 deletions

View file

@ -5,7 +5,11 @@ mod wasm_bridge;
mod watch_filesystem;
mod zellij_exports;
use log::info;
use std::{collections::HashMap, fs, path::PathBuf};
use std::{
collections::{HashMap, HashSet},
fs,
path::PathBuf,
};
use wasmer::Store;
use crate::screen::ScreenInstruction;
@ -14,7 +18,7 @@ use crate::{pty::PtyInstruction, thread_bus::Bus, ClientId, ServerInstruction};
use wasm_bridge::WasmBridge;
use zellij_utils::{
data::{Event, PluginCapabilities},
data::{Event, EventType, PluginCapabilities},
errors::{prelude::*, ContextType, PluginContext},
input::{
command::TerminalAction,
@ -74,6 +78,7 @@ pub enum PluginInstruction {
String, // serialized message
String, // serialized payload
),
PluginSubscribedToEvents(PluginId, ClientId, HashSet<EventType>),
Exit,
}
@ -97,6 +102,9 @@ impl From<&PluginInstruction> for PluginContext {
PluginContext::PostMessageToPluginWorker
},
PluginInstruction::PostMessageToPlugin(..) => PluginContext::PostMessageToPlugin,
PluginInstruction::PluginSubscribedToEvents(..) => {
PluginContext::PluginSubscribedToEvents
},
}
}
}
@ -267,6 +275,17 @@ pub(crate) fn plugin_thread_main(
)];
wasm_bridge.update_plugins(updates)?;
},
PluginInstruction::PluginSubscribedToEvents(_plugin_id, _client_id, events) => {
for event in events {
if let EventType::FileSystemCreate
| EventType::FileSystemRead
| EventType::FileSystemUpdate
| EventType::FileSystemDelete = event
{
wasm_bridge.start_fs_watcher_if_not_started();
}
}
},
PluginInstruction::Exit => {
wasm_bridge.cleanup();
break;

View file

@ -553,7 +553,7 @@ pub fn can_subscribe_to_hd_events() {
received_screen_instructions,
ScreenInstruction::PluginBytes,
screen_receiver,
3
2
);
let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id));
@ -565,12 +565,8 @@ pub fn can_subscribe_to_hd_events() {
client_id,
size,
));
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
None,
Some(client_id),
Event::InputReceived,
)])); // will be cached and sent to the plugin once it's loaded
std::thread::sleep(std::time::Duration::from_millis(100));
// extra long time because we only start the fs watcher on plugin load
std::thread::sleep(std::time::Duration::from_millis(5000));
std::fs::OpenOptions::new()
.create(true)
.write(true)

View file

@ -75,13 +75,7 @@ impl WasmBridge {
let connected_clients: Arc<Mutex<Vec<ClientId>>> = Arc::new(Mutex::new(vec![]));
let plugin_cache: Arc<Mutex<HashMap<PathBuf, Module>>> =
Arc::new(Mutex::new(HashMap::new()));
let watcher = match watch_filesystem(senders.clone(), &zellij_cwd) {
Ok(watcher) => Some(watcher),
Err(e) => {
log::error!("Failed to watch filesystem: {:?}", e);
None
},
};
let watcher = None;
WasmBridge {
connected_clients,
plugins,
@ -697,6 +691,17 @@ impl WasmBridge {
}
Ok(())
}
pub fn start_fs_watcher_if_not_started(&mut self) {
if self.watcher.is_none() {
self.watcher = match watch_filesystem(self.senders.clone(), &self.zellij_cwd) {
Ok(watcher) => Some(watcher),
Err(e) => {
log::error!("Failed to watch filesystem: {:?}", e);
None
},
};
}
}
}
fn handle_plugin_successful_loading(senders: &ThreadSenders, plugin_id: PluginId) {

View file

@ -26,7 +26,7 @@ use zellij_utils::{
input::{
actions::Action,
command::{RunCommand, RunCommandAction, TerminalAction},
layout::{Layout, RunPlugin, RunPluginLocation},
layout::Layout,
plugins::PluginType,
},
serde,
@ -146,8 +146,17 @@ impl ForeignFunctionEnv {
fn host_subscribe(env: &ForeignFunctionEnv) {
wasi_read_object::<HashSet<EventType>>(&env.plugin_env.wasi_env)
.and_then(|new| {
env.subscriptions.lock().to_anyhow()?.extend(new);
Ok(())
env.subscriptions.lock().to_anyhow()?.extend(new.clone());
Ok(new)
})
.and_then(|new| {
env.plugin_env
.senders
.send_to_plugin(PluginInstruction::PluginSubscribedToEvents(
env.plugin_env.plugin_id,
env.plugin_env.client_id,
new,
))
})
.with_context(|| format!("failed to subscribe for plugin {}", env.plugin_env.name()))
.fatal();

View file

@ -929,7 +929,6 @@ impl Screen {
self.character_cell_size.clone(),
);
let mut tabs_to_close = vec![];
let size = self.size;
for (tab_index, tab) in &mut self.tabs {
if tab.has_selectable_tiled_panes() {
tab.render(&mut output).context(err_context)?;

View file

@ -370,6 +370,7 @@ pub enum PluginContext {
ApplyCachedWorkerMessages,
PostMessageToPluginWorker,
PostMessageToPlugin,
PluginSubscribedToEvents,
}
/// Stack call representations corresponding to the different types of [`ClientInstruction`]s.