fix(runtime): clean up sessions on disconnect (#17)

* fix(runtime): clean up sessions on disconnect

* chore(ci): match Biome 2.4 formatting

* ci: retry stalled Rust job

* test: bind daemon ports without probe races
This commit is contained in:
NianJiu
2026-08-12 18:44:22 +08:00
committed by GitHub
parent c75f97119d
commit 1371c92721
8 changed files with 261 additions and 24 deletions
+3 -4
View File
@@ -539,10 +539,9 @@ pub async fn stop_session(
Ok(result)
}
Err(DispatchError::Rpc(err)) => {
// After an extension SW restart the daemon still owns the
// session entry (the generation-guard ensures we do not
// purge across reconnects), but the extension's in-memory
// SessionManager is reset and now answers `not_found`.
// A legacy extension or an unusual reconnect race may still
// leave a daemon session after the extension's in-memory
// SessionManager has reset and now answers `not_found`.
// Treat that as an authoritative signal that the session is
// already gone and reconcile our local state instead of
// leaving an orphan row visible to `bsk session list`
+11
View File
@@ -286,6 +286,17 @@ async fn drive_connection(
// socket's cleanup path uses `remove_if_generation_matches` to
// avoid clobbering the newer entry (review M4/M5 round 2 #1).
let browser_id = BrowserId(params.instance_id.clone());
// A fresh socket represents a fresh extension control plane. The
// extension tears down its local sessions before reconnecting, so any
// daemon-side sessions left under the same instance id are stale. Purge
// them before replacing the browser registration; otherwise an old WS
// cleanup racing with this handshake can preserve rows that no longer
// have an Agent Window on the extension side.
for session in state.sessions.purge_browser(&browser_id) {
state.tool_queues.remove(&session.id);
state.session_interrupts.drop_session(&session.id);
debug!(session = %session.id, "purged stale session before browser reconnect");
}
let (tx, mut rx) = mpsc::unbounded_channel::<Frame>();
let generation = super::browsers::next_browser_generation();
let connected_at_ms = std::time::SystemTime::now()