mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
## Problem During rolling deploys, the chat stream WebSocket disconnects and the user sees **"Chat stream disconnected."** permanently with no recovery other than a full page refresh. ## Changes Add automatic WebSocket reconnection with capped exponential backoff (1s → 2s → 4s → … → 10s max) to the chat stream `useEffect` in `ChatContext.ts`. **`ChatContext.ts`** - Wrap socket creation in a `connect()` function that can be retried on disconnect. - On `error` or `close`, schedule a reconnect with exponential backoff via `scheduleReconnect()`. - Guard against double scheduling when both `error` and `close` fire for the same disconnect (`disconnected` flag per connection). - On successful reconnect (`open` event), reset backoff and clear `streamError`. - Pass the latest `lastMessageIdRef` on each reconnect so the server replays only unseen durable messages via `after_id`. - Add `RECONNECT_BASE_MS` (1s) and `RECONNECT_MAX_MS` (10s) constants. **`ChatContext.test.tsx`** - Extend mock socket with `emitOpen()` and `emitClose()` helpers. - Update existing disconnect tests for new reconnect behavior. - Add **"sets streamError on WebSocket disconnect and reconnects"** — verifies error banner appears, reconnect fires, and error clears on open. - Add **"uses exponential backoff on consecutive disconnects"** — verifies increasing delays between reconnects. - Add **"passes latest message ID on reconnect for catch-up"** — verifies `after_id` is forwarded on each reconnect. ### User experience - **Before**: "Chat stream disconnected." — permanent, requires page refresh - **After**: "Chat stream disconnected. Reconnecting…" — auto-recovers within seconds ### Limitations `message_part` events (streaming LLM tokens) are ephemeral / in-memory only. If the processing replica dies mid-step, those partial tokens are lost regardless of reconnect. The backend's stale-chat recovery will re-run the step on a new replica; the reconnect ensures the client is connected to see that happen.