Skip to content

Commit 03543a3

Browse files
committed
refactor(hu): abort leaked plugin tasks, harden config, drop legacy world
Address PR #236 review findings in crates/hiroz-union: - Abort background tokio tasks on drop: add Drop impls that call AbortHandle::abort() for subscription/raw-sub/liveliness/queryable/ rate-tracker state, and break the rate-tracker loop when the receiver is gone. Prevents unbounded task accumulation across plugin reload. - Share a single process-wide WASM engine (OnceLock) with one epoch ticker for its lifetime, instead of spawning a fresh engine+ticker on every load_plugins/load_plugin_named call. - Escape untrusted manifest endpoints through serde_json when building the connect/endpoints config array (was raw format! interpolation). - Deduplicate load_plugins/load_plugin_named into a shared load_from. - Replace the DispatchOutcome enum with Option<u32> and update callers. - Remove the never-shipped v0.3 legacy hu-plugin alias world: PluginBindings::Legacy, try_load_legacy, plugin-event variant, and the tui_bindgen module (the top-level bindgen now targets hu-tui-plugin). - Drop the deprecated --headless/--web CLI flags.
1 parent 60d1a8e commit 03543a3

6 files changed

Lines changed: 116 additions & 214 deletions

File tree

crates/hiroz-union/src/main.rs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ struct Cli {
5454
#[arg(long, value_enum, default_value = "rmw-zenoh", global = true)]
5555
backend: Backend,
5656

57-
/// Deprecated: use `hu stream`. JSON streaming to stdout.
58-
#[arg(long, global = true, hide = true)]
59-
headless: bool,
60-
6157
/// Output structured JSON logs
6258
#[arg(long, global = true)]
6359
json: bool,
@@ -74,10 +70,6 @@ struct Cli {
7470
#[arg(long = "echo", value_name = "TOPIC", global = true)]
7571
echo_topics: Vec<String>,
7672

77-
/// Deprecated: use `hu web`. Start the web plugin server (default port 8080).
78-
#[arg(long, value_name = "PORT", global = true, hide = true)]
79-
web: Option<Option<u16>>,
80-
8173
#[command(subcommand)]
8274
command: Option<Commands>,
8375
}
@@ -185,29 +177,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
185177
Some(Commands::External(args)) => run_cli_frontend(args, core, &router).await?,
186178
// Plugin/Router are handled and returned above.
187179
Some(Commands::Plugin { .. }) | Some(Commands::Router { .. }) => unreachable!(),
188-
// Default + the deprecated --export / --web / --headless flags.
180+
// Default: bare `hu`, plus the deprecated `--export` flag.
189181
None => {
190182
if let Some(path) = cli.export {
191183
frontend::launch(frontend::Export { path }, core, &router).await?
192-
} else if let Some(port) = cli.web {
193-
frontend::launch(
194-
frontend::Web {
195-
port: port.unwrap_or(8080),
196-
},
197-
core,
198-
&router,
199-
)
200-
.await?
201-
} else if cli.headless {
202-
frontend::launch(
203-
frontend::Stream {
204-
json: cli.json,
205-
echo: cli.echo_topics,
206-
},
207-
core,
208-
&router,
209-
)
210-
.await?
211184
} else {
212185
frontend::launch(frontend::Tui, core, &router).await?
213186
}

crates/hiroz-union/src/modes/cli.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ pub async fn run_cli_plugin(
6969
.await;
7070
}
7171

72-
let exit_code = plugin
73-
.dispatch_cli_event(CliEvent::Startup(args))
74-
.exit_code();
72+
let exit_code = plugin.dispatch_cli_event(CliEvent::Startup(args));
7573
flush_output(plugin);
7674
if let Some(code) = exit_code {
7775
return Ok(code);
@@ -91,7 +89,7 @@ pub async fn run_cli_plugin(
9189
// a Tick.
9290
if raw_tick_ms == 0 {
9391
let _ = sigint_rx.await;
94-
let interrupt_code = plugin.dispatch_cli_event(CliEvent::Interrupt).exit_code();
92+
let interrupt_code = plugin.dispatch_cli_event(CliEvent::Interrupt);
9593
flush_output(plugin);
9694
return Ok(interrupt_code.unwrap_or(130));
9795
}
@@ -101,19 +99,19 @@ pub async fn run_cli_plugin(
10199

102100
loop {
103101
if sigint_rx.try_recv().is_ok() {
104-
let interrupt_code = plugin.dispatch_cli_event(CliEvent::Interrupt).exit_code();
102+
let interrupt_code = plugin.dispatch_cli_event(CliEvent::Interrupt);
105103
flush_output(plugin);
106104
if let Some(code) = interrupt_code {
107105
return Ok(code);
108106
}
109-
let code = plugin.dispatch_cli_event(CliEvent::Tick).exit_code();
107+
let code = plugin.dispatch_cli_event(CliEvent::Tick);
110108
flush_output(plugin);
111109
return Ok(code.unwrap_or(130));
112110
}
113111

114112
tokio::time::sleep(tick_interval).await;
115113

116-
let code = plugin.dispatch_cli_event(CliEvent::Tick).exit_code();
114+
let code = plugin.dispatch_cli_event(CliEvent::Tick);
117115
flush_output(plugin);
118116
if let Some(c) = code {
119117
return Ok(c);

crates/hiroz-union/src/plugin/wasm/host/mod.rs

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ pub mod transport;
77

88
use wasmtime::component::bindgen;
99

10-
// Legacy / TUI world — used for backward compat and for instantiating hu-plugin
11-
// (v0.3) components. All Host trait impls on PluginState live here.
10+
// TUI world — this bindgen also generates the shared `hu::plugin::*` interface
11+
// modules and their Host traits, which the CLI and web worlds below reuse via
12+
// `with:` directives. All Host trait impls on PluginState live here.
1213
bindgen!({
13-
world: "hu-plugin",
14+
world: "hu-tui-plugin",
1415
path: "wit/v0.1/hu-plugin.wit",
1516
});
1617

@@ -32,24 +33,6 @@ pub mod cli_bindgen {
3233
});
3334
}
3435

35-
/// TUI-world bindings (new hu-tui-plugin world — same interfaces as legacy
36-
/// hu-plugin but exports on-event(tui-event) instead of on-event(plugin-event)).
37-
pub mod tui_bindgen {
38-
use wasmtime::component::bindgen;
39-
bindgen!({
40-
world: "hu-tui-plugin",
41-
path: "wit/v0.1/hu-plugin.wit",
42-
with: {
43-
"hu:plugin/types": super::hu::plugin::types,
44-
"hu:plugin/graph": super::hu::plugin::graph,
45-
"hu:plugin/ros": super::hu::plugin::ros,
46-
"hu:plugin/render": super::hu::plugin::render,
47-
"hu:plugin/raw-transport": super::hu::plugin::raw_transport,
48-
"hu:plugin/session": super::hu::plugin::session,
49-
}
50-
});
51-
}
52-
5336
/// Web-world bindings. Only imports graph and ros (no TUI render interface).
5437
pub mod web_bindgen {
5538
use wasmtime::component::bindgen;

0 commit comments

Comments
 (0)