Skip to content

feat(ws): handle shutdown message for graceful destroy#30

Open
ysyneu wants to merge 1 commit intomainfrom
feat/ws-shutdown-handler
Open

feat(ws): handle shutdown message for graceful destroy#30
ysyneu wants to merge 1 commit intomainfrom
feat/ws-shutdown-handler

Conversation

@ysyneu
Copy link
Copy Markdown
Collaborator

@ysyneu ysyneu commented Apr 11, 2026

Summary

  • New protocol.MessageTypeShutdown and matching Handler.handleShutdown so Safari can tell a runner to drop everything and exit cleanly, without waiting on the 5s force-unregister timeout.
  • handleShutdown cancels all in-flight tasks, waits up to 2s for tool results to flush, then closes the WebSocket client so RunWithReconnect returns nil instead of entering the reconnect loop.

Why

Sibling PR: fc-safari feat/ai-sre branch, commit d505589 feat(cloud-sandbox): end-to-end provisioning + auto-pause lifecycle. Safari's CloudManager.disconnectRunner sends this message whenever a cloud sandbox is torn down (session end, idle recycle, eviction). Before this change every cloud sandbox destroy hit the 5s timeout because the runner silently ignored the unknown shutdown type and stayed in its reconnect loop until the server-side unregister finally fired.

Test plan

  • go build ./... — clean
  • go vet ./... — clean
  • Verified on the ACS dev cluster 2026-04-11: Safari's CloudManager.GracefulShutdowndisconnectRunner now completes in ~2s instead of hitting the 5s warn-and-force-unregister path. Recycle log shows kind=cloud disconnect with no warning.
  • Reviewer to confirm the 2s WaitForTasks window is compatible with the longest-running in-flight tool (bash scripts, MCP calls).

🤖 Generated with Claude Code

Adds a new protocol.MessageTypeShutdown and a matching Handler.handleShutdown
so Safari can cleanly tear down a cloud sandbox's runner without waiting
on the 5s force-unregister timeout.

Flow when CloudManager.disconnectRunner sends a shutdown message:
1. Handler cancels all in-flight tasks via CancelAllTasks.
2. Waits up to 2s for in-flight tool results to flush via WaitForTasks —
   well inside Safari's 5s force-unregister window.
3. Closes the WebSocket client, which sets c.closed so RunWithReconnect
   returns nil instead of entering the reconnect loop.

Before this change, every cloud sandbox destroy hit the 5s timeout because
the runner silently ignored the shutdown message and stayed in its
reconnect loop until the server-side unregister finally fired.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant