Skip to content

feat: Show a disconnect dialog for lost DuckDB WebSocket connections - #763

Merged
ilyabo merged 3 commits into
mainfrom
show-disconnect-notification
Jun 23, 2026
Merged

ilyabo merged 3 commits into
mainfrom
show-disconnect-notification

Conversation

@ilyabo

@ilyabo ilyabo commented Jun 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Add persistent WebSocket connection status tracking to the DuckDB connector.
  • Surface connection lifecycle changes through a new reconnect API and subscription hook.
  • Show a CLI UI dialog when the local SQLRooms server disconnects, with manual retry and auto-reconnect.
  • Document the new connection-status APIs in the DuckDB package README.

Testing

  • Not run (not requested)

Summary by CodeRabbit

  • New Features

    • Added connection loss detection and recovery dialog for DuckDB connections
    • Automatic reconnection with exponential backoff and visible retry feedback
    • Manual retry option available when connection is lost
    • Database table schemas automatically refresh upon successful reconnection
  • Documentation

    • Added guidance on monitoring WebSocket DuckDB connection status and implementing reconnect handlers

@ilyabo ilyabo changed the title Show a disconnect dialog for lost DuckDB WebSocket connections feat: Show a disconnect dialog for lost DuckDB WebSocket connections Jun 23, 2026
@coderabbitai

coderabbitai Bot commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@ilyabo, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 15 minutes and 42 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 33683b25-961e-4fa3-9024-747e830b3a67

📥 Commits

Reviewing files that changed from the base of the PR and between 6e68f63 and 02e0fbc.

📒 Files selected for processing (2)
  • apps/sqlrooms-cli-ui/src/components/CliDuckDbConnectionLostDialog.tsx
  • packages/duckdb/src/connectors/WebSocketDuckDbConnector.ts
📝 Walkthrough

Walkthrough

Adds connection status tracking (idle | connecting | connected | disconnected) and a reconnect() method to WebSocketDuckDbConnector, exposing internal status transitions via a subscriber API. The CLI store exports the connector instance and WebSocket URL. A new CliDuckDbConnectionLostDialog component monitors status, auto-reconnects with exponential backoff, and is rendered in the CLI room layout.

Changes

DuckDB WebSocket reconnect and connection-lost dialog

Layer / File(s) Summary
WebSocket connector: status type, state machine, and reconnect API
packages/duckdb/src/connectors/WebSocketDuckDbConnector.ts, packages/duckdb/src/index.ts
Adds WebSocketDuckDbConnectionStatus type and onConnectionStatusChange option; introduces internal connectionStatus state and a setConnectionStatus helper; transitions status in ensureSocket, ws.onerror, ws.onclose, and destroyInternal; exposes connectionStatus, subscribeConnectionStatus(), and reconnect() on the returned connector; re-exports the type from the package index.
CLI store connector/URL exports and README docs
apps/sqlrooms-cli-ui/src/store.ts, packages/duckdb/README.md
Exports cliDuckDbWsUrl and cliDuckDbConnector from the CLI store so the dialog can import the live instance. Adds a README section documenting connectionStatus, subscribeConnectionStatus, onConnectionStatusChange, and reconnect().
CliDuckDbConnectionLostDialog: hook, state machine, and UI
apps/sqlrooms-cli-ui/src/components/CliDuckDbConnectionLostDialog.tsx, apps/sqlrooms-cli-ui/src/room.tsx
Implements useDuckDbConnectionStatus via useSyncExternalStore, backoff helpers, and the full dialog: detects connected→disconnected transitions, runs auto-reconnect with exponential backoff, exposes a manual Retry button, refreshes DB schemas on success, and renders retrying/error state. Wires the dialog into the SidebarInset in room.tsx.

Sequence Diagram

sequenceDiagram
  participant UI as CliDuckDbConnectionLostDialog
  participant Connector as WebSocketDuckDbConnector
  participant WS as WebSocket
  participant RoomStore as roomStore

  WS-->>Connector: ws.onclose (unexpected)
  Connector->>Connector: setConnectionStatus('disconnected')
  Connector-->>UI: subscribeConnectionStatus listener fired

  Note over UI: Opens dialog, schedules auto-retry

  loop Exponential backoff
    UI->>Connector: reconnect()
    Connector->>WS: new WebSocket(wsUrl)
    WS-->>Connector: ws.onopen → setConnectionStatus('connected')
    Connector-->>UI: status = 'connected'
    alt Reconnect succeeded
      UI->>RoomStore: refreshDbTableSchemas()
      UI->>UI: close dialog
    else Reconnect failed
      UI->>UI: increment attempt, schedule next retry with backoff
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 The socket went dark, but I didn't despair,
I counted my hops with exponential care.
connecting → connected — the tunnel shone bright,
The dialog closed and the schemas felt right.
One reconnect() away from the light! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a disconnect dialog for lost DuckDB WebSocket connections, which aligns with the primary objective and the new CliDuckDbConnectionLostDialog component.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch show-disconnect-notification

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/sqlrooms-cli-ui/src/components/CliDuckDbConnectionLostDialog.tsx (1)

41-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add TSDoc for the exported CliDuckDbConnectionLostDialog function.

As per coding guidelines, **/*.{ts,tsx}: Add tsdoc to exported types and functions.

📝 Proposed fix
+/**
+ * Modal dialog shown when the CLI DuckDB WebSocket disconnects.
+ * Provides manual retry and background auto-reconnect behavior.
+ */
 export function CliDuckDbConnectionLostDialog() {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/sqlrooms-cli-ui/src/components/CliDuckDbConnectionLostDialog.tsx` at
line 41, The exported function CliDuckDbConnectionLostDialog is missing TSDoc
documentation comments. Add a TSDoc comment block above the function declaration
to document its purpose and any relevant details about the component. Include a
brief description of what the component does enclosed in /** */ with appropriate
`@param` and `@returns` tags if applicable.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/sqlrooms-cli-ui/src/components/CliDuckDbConnectionLostDialog.tsx`:
- Around line 97-123: The auto-reconnect effect in the useEffect starting at
line 98 is guarded by !isOpen, which causes reconnection attempts to halt when
users dismiss the dialog via Escape or overlay click. Replace the !isOpen check
with !hasConnectedRef.current to keep reconnection attempts active based on
connection history rather than dialog visibility, and remove isOpen from the
dependency array of the useEffect hook. Additionally, add TSDoc comments to the
exported component at line 41 following the coding guidelines for *.ts and *.tsx
files.

In `@packages/duckdb/src/connectors/WebSocketDuckDbConnector.ts`:
- Around line 224-228: When the auth handshake fails with type 'error' in the
WebSocket message handler, the socket is not being closed and cleared after
rejecting the promise. This leaves the socket reference open, causing subsequent
ensureSocket() calls to treat it as a healthy connection and preventing proper
reconnection. In the error handling block where t === 'error', after setting
opening to null and rejecting the promise, you need to also close the socket
connection and clear the socket reference (similar to how socket cleanup is
typically handled in disconnect scenarios) to ensure a fresh connection attempt
on the next ensureSocket() call.

---

Nitpick comments:
In `@apps/sqlrooms-cli-ui/src/components/CliDuckDbConnectionLostDialog.tsx`:
- Line 41: The exported function CliDuckDbConnectionLostDialog is missing TSDoc
documentation comments. Add a TSDoc comment block above the function declaration
to document its purpose and any relevant details about the component. Include a
brief description of what the component does enclosed in /** */ with appropriate
`@param` and `@returns` tags if applicable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0e889ccf-9519-462b-b1cf-8d15338a6a53

📥 Commits

Reviewing files that changed from the base of the PR and between 28e6cd5 and 6e68f63.

📒 Files selected for processing (6)
  • apps/sqlrooms-cli-ui/src/components/CliDuckDbConnectionLostDialog.tsx
  • apps/sqlrooms-cli-ui/src/room.tsx
  • apps/sqlrooms-cli-ui/src/store.ts
  • packages/duckdb/README.md
  • packages/duckdb/src/connectors/WebSocketDuckDbConnector.ts
  • packages/duckdb/src/index.ts

@ilyabo
ilyabo merged commit 213239f into main Jun 23, 2026
4 checks passed
@ilyabo
ilyabo deleted the show-disconnect-notification branch June 23, 2026 07:47
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