Description
PluginManager::update_one_plugin (an async fn) contains two blocking std::fs calls that execute directly on the async executor thread after the main spawn_blocking block completes:
- Line 830:
std::fs::write(&source_dest, toml_str) — writes source metadata
- Line 834:
std::fs::read_to_string(plugin.path.join(".plugin.toml")) — reads the updated manifest to detect the new version
These calls block the Tokio thread pool for the duration of the I/O. Under concurrent auto-update checks (check_auto_updates spawns N tasks via join_all) this can saturate the executor.
Reproduction Steps
- Configure multiple remote plugins in
~/.local/share/zeph/plugins/
- Enable
auto_update = true in config
- Observe: agent operations may stall during concurrent auto-update tasks
Expected Behavior
All blocking filesystem operations inside async functions must be wrapped in tokio::task::spawn_blocking or replaced with tokio::fs equivalents.
Actual Behavior
std::fs::write and std::fs::read_to_string called directly on the async executor after the spawn_blocking block, at crates/zeph-plugins/src/manager.rs lines ~830–834.
Fix
Move both calls into the existing apply_staged_update spawn_blocking closure, or wrap in a separate tokio::task::spawn_blocking.
Description
PluginManager::update_one_plugin(anasync fn) contains two blockingstd::fscalls that execute directly on the async executor thread after the mainspawn_blockingblock completes:std::fs::write(&source_dest, toml_str)— writes source metadatastd::fs::read_to_string(plugin.path.join(".plugin.toml"))— reads the updated manifest to detect the new versionThese calls block the Tokio thread pool for the duration of the I/O. Under concurrent auto-update checks (
check_auto_updatesspawnsNtasks viajoin_all) this can saturate the executor.Reproduction Steps
~/.local/share/zeph/plugins/auto_update = truein configExpected Behavior
All blocking filesystem operations inside async functions must be wrapped in
tokio::task::spawn_blockingor replaced withtokio::fsequivalents.Actual Behavior
std::fs::writeandstd::fs::read_to_stringcalled directly on the async executor after thespawn_blockingblock, atcrates/zeph-plugins/src/manager.rslines ~830–834.Fix
Move both calls into the existing
apply_staged_updatespawn_blockingclosure, or wrap in a separatetokio::task::spawn_blocking.