pub struct ActionBridge { /* private fields */ }Expand description
The host-side bridge carried in [PluginApiVt::user_data] so
trampoline_runtime_action can recover the harness state from any thread.
runtime: Handle is captured at build time (the host is on the runtime when
it constructs the bridge) — this is the foreign-thread fix. host is the
rpi-cli impl over the harness. reload is a CLI-owned callback that
re-runs extension discovery + Part-A loaders (a CLI concern, NOT a harness
op) — wired by rpi-cli in B5d via reload_callback_from_mailbox.
§Staleness (B5d)
active: Arc<AtomicBool> is shared with a ReloadMailbox-driven swap
site. A /reload (TUI command OR a plugin’s runtime_action(Reload)) builds
a fresh ExtensionSession + a fresh ActionBridge, calls
invalidate on the old bridge, and swaps the new one in.
In-flight runtime_action calls that recovered the OLD bridge from
user_data (the pointer a plugin stored during the prior register) then
hit the staleness guard in [run_action] and fail with a structured error
instead of driving a half-swapped harness. (Plugins load fresh on reload,
handing them the NEW bridge pointer; the guard only catches the race window
where an old call is still parked on rx.recv().)
Held behind Arc (pointer-stable for the bridge’s lifetime via
Arc::as_ptr); rpi-cli keeps one clone for the session lifetime so the
pointer a plugin stored during register stays valid post-register. (The
transient HostApi built per load_one holds a clone only during register
— when it drops after take_registry, the master Arc in rpi-cli keeps
the allocation alive.)
Implementations§
Source§impl ActionBridge
impl ActionBridge
Sourcepub fn new(runtime: Handle, host: Arc<dyn RuntimeActionHost>) -> Arc<Self> ⓘ
pub fn new(runtime: Handle, host: Arc<dyn RuntimeActionHost>) -> Arc<Self> ⓘ
Build a bridge. The Handle MUST be captured from a thread running the
target runtime (pi-cli builds the bridge on the async main thread).
Sourcepub fn with_reload(
runtime: Handle,
host: Arc<dyn RuntimeActionHost>,
reload: Arc<dyn Fn() -> BoxFuture<'static, ()> + Send + Sync>,
) -> Arc<Self> ⓘ
pub fn with_reload( runtime: Handle, host: Arc<dyn RuntimeActionHost>, reload: Arc<dyn Fn() -> BoxFuture<'static, ()> + Send + Sync>, ) -> Arc<Self> ⓘ
Same as new with a reload callback (B5d wires this via
reload_callback_from_mailbox).
Sourcepub fn invalidate(&self)
pub fn invalidate(&self)
Mark this bridge stale (B5d). A /reload that swaps in a fresh bridge
calls this on the old one so in-flight runtime_action calls parked on
the old user_data pointer fail fast with a staleness error instead of
driving the swapped-out session. Idempotent.
Sourcepub fn clone_host(&self) -> Arc<dyn RuntimeActionHost> ⓘ
pub fn clone_host(&self) -> Arc<dyn RuntimeActionHost> ⓘ
B5d: clone the host impl so a /reload can build a FRESH ActionBridge
over the SAME RuntimeActionHost (the host’s harness cell already points
at the live harness — the harness is NOT rebuilt on reload — so the host
is reusable across reloads; only the bridge’s staleness flag + reload
callback differ). The fresh bridge gets a fresh active flag (true) +
the reload callback the TUI installed; the old bridge is invalidated.