Complete WebSocket reconnect, pending-request, and connection-state handling #10

Closed
opened 2026-07-30 04:06:00 +00:00 by lost-rob0t · 0 comments
lost-rob0t commented 2026-07-30 04:06:00 +00:00 (Migrated from github.com)

Problem

The frontend control-plane client in PR #3 does not meet its reconnect contract.

On socket close, pending requests remain unresolved until their individual timeout expires. After reconnect, the client does not request a fresh workspace snapshot. The client internally creates connection-state handlers but exposes no API for the UI to observe connection state.

Found during review of PR #3.

Required changes

  • Reject every pending request immediately when the socket closes.
  • Ensure request timers are always cleared exactly once.
  • Expose a typed connection-state subscription API.
  • Distinguish connecting, connected, reconnecting, disconnected, and disposed states.
  • After every reconnect, request an authoritative workspace.snapshot before declaring the durable projection synchronized.
  • Prevent duplicate sockets and duplicate reconnect timers.
  • Make initialization safe under React StrictMode and hot reload.
  • Decide and document whether safe/idempotent commands are retried; never replay mutations blindly.
  • Reset or reconcile per-workspace revision/deduplication state after the snapshot.
  • Surface connection failure through the existing UI status/notice system.

Acceptance criteria

  • Socket close immediately rejects all pending requests with control-plane.unavailable.
  • Reconnect uses bounded backoff with no overlapping attempts.
  • A successful reconnect fetches and applies a fresh snapshot.
  • React remounting does not create duplicate connections or handlers.
  • Unit tests cover correlation, timeout, close rejection, reconnect, snapshot refresh, dispose, and StrictMode-style reinitialization.

Related PR: #3

## Problem The frontend control-plane client in PR #3 does not meet its reconnect contract. On socket close, pending requests remain unresolved until their individual timeout expires. After reconnect, the client does not request a fresh workspace snapshot. The client internally creates connection-state handlers but exposes no API for the UI to observe connection state. Found during review of PR #3. ## Required changes - Reject every pending request immediately when the socket closes. - Ensure request timers are always cleared exactly once. - Expose a typed connection-state subscription API. - Distinguish connecting, connected, reconnecting, disconnected, and disposed states. - After every reconnect, request an authoritative `workspace.snapshot` before declaring the durable projection synchronized. - Prevent duplicate sockets and duplicate reconnect timers. - Make initialization safe under React StrictMode and hot reload. - Decide and document whether safe/idempotent commands are retried; never replay mutations blindly. - Reset or reconcile per-workspace revision/deduplication state after the snapshot. - Surface connection failure through the existing UI status/notice system. ## Acceptance criteria - Socket close immediately rejects all pending requests with `control-plane.unavailable`. - Reconnect uses bounded backoff with no overlapping attempts. - A successful reconnect fetches and applies a fresh snapshot. - React remounting does not create duplicate connections or handlers. - Unit tests cover correlation, timeout, close rejection, reconnect, snapshot refresh, dispose, and StrictMode-style reinitialization. Related PR: #3
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/quasar#10
No description provided.