fix(remote): close the /acp session cleanly on disconnect + app exit - #57
Merged
Merged
Conversation
Previously neither the Disconnect button nor app close released the server-side session: `disconnect()` only `task.abort()`ed (dropping the socket with no WS Close), and there was no app-teardown hook at all — so a closed/quit Studio left its `/acp` session lingering on the gateway until its TTL (session_ttl_hours=1) or liveness reaper fired. With max_sessions=3 that can exhaust the slots across connect/quit churn. 1. Graceful disconnect: `disconnect()` now signals the live loop (OutMsg::Shutdown) to abandon any in-flight turn (session/cancel) and send a WS Close frame before the task ends, so the gateway sees an intentional close (not a resumable blip) and frees the slot immediately. A shared `stop` flag makes run_reconnecting stop instead of reconnecting; a 400ms flush window + abort backstop bound the teardown. 2. App-exit hook: switch the tauri builder to build()+run() and call disconnect() on RunEvent::ExitRequested, covering Cmd-Q / window close. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
For the current build, neither closing the app nor clicking Disconnect releases the server-side
/acpsession:disconnect()only didtask.abort()— the WS socket is dropped with no Close frame, and by the resume-on-reconnect design the gateway keeps the session alive for a resume that never comes..run(generate_context!())with noRunEventhandler), so Cmd-Q / window close never even calleddisconnect().Net: a quit/closed Studio leaves its session lingering on the gateway until
session_ttl_hours=1or the liveness reaper fires. Withmax_sessions=3, connect/quit churn can exhaust the slots.Fix
disconnect()now signals the live loop (OutMsg::Shutdown) to abandon any in-flight turn (session/cancel) and send a WS Close frame before the task ends, so the gateway sees an intentional close (not a resumable blip) and frees the slot immediately. A sharedstopflag makesrun_reconnectingstop instead of reconnecting; a 400 ms flush window +abort()backstop bound the teardown.build()+run(|app, event| …); onRunEvent::ExitRequestedit callsdisconnect(), covering Cmd-Q / window close.Verification
rustfmt --checkparses both files clean; wiring reviewed.src-tauri(no GTK).🤖 Generated with Claude Code