You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Enforce single active GUI connection with proper race condition handling
- Add async locking mechanism to prevent race conditions during connection setup
- Wait for existing connection setup to complete before accepting new connection
- Remove event listeners from old connection before closing to prevent interference
- Add timeout failsafe (2 seconds) to prevent deadlocks
- Frontend detects "Replaced by new connection" and shows appropriate message
- No reconnection attempts when connection is explicitly replaced
- Update CLAUDE.md with single-connection behavior documentation
- Bump version to 1.1.5
Fixes issue where multiple tabs could remain connected simultaneously due to race conditions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Copy file name to clipboardExpand all lines: CLAUDE.md
+10-2Lines changed: 10 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -140,11 +140,17 @@ This is a **pnpm workspaces + Turborepo** monorepo (converted from standalone ap
140
140
- WebSocket auto-detects URL from browser (supports both direct access and nginx proxy)
141
141
- Auto-detection: `ws://localhost:5173/remote-control` (dev) or `ws://localhost:8080/remote-control` (Docker)
142
142
- Protocol switches to `wss://` for HTTPS connections
143
+
-**Single Active Connection**: Only one GUI can control the diagram at a time
144
+
- When a new GUI connects, the previous connection is gracefully closed
145
+
- Old GUI shows "AI Assistant disconnected - connection taken over by another tab/window"
146
+
- Prevents confusion from multiple tabs trying to control the same backend
143
147
- Commands are handled by contexts (`DiagramContext`, `AreasContext`, `NotesContext`, etc.)
144
148
- Automatic reconnection with exponential backoff (max 10 attempts, up to 30s delay with jitter)
145
-
- Connection status displayed via Toast notifications ("AI Assistant connected/disconnected")
149
+
- Exception: Won't reconnect if connection was replaced by another session
150
+
- Connection status displayed via Toast notifications and persistent status badge
146
151
- All commands processed through `useRemoteControl.js:152` switch statement
147
152
- Command timeout: 30 seconds (configured in `DrawDBClientService:15`)
153
+
- Heartbeat: Frontend sends ping every 30 seconds to keep connection alive
148
154
149
155
### Backend (apps/backend)
150
156
@@ -402,6 +408,8 @@ function MyComponent() {
402
408
403
409
-**WebSocket connection fails**: Check that `VITE_REMOTE_CONTROL_ENABLED=true` and backend is running
404
410
-**MCP tools timeout**: Default timeout is 30s (configured in `DrawDBClientService:15`)
411
+
-**Multiple tabs/windows**: Only one GUI can be connected at a time. Opening a new tab will disconnect the previous one with message "connection taken over by another tab/window"
412
+
-**Connection replaced**: If you see "connection taken over", another tab/window is now active. Close it or refresh this tab to reconnect
405
413
-**Docker nginx issues**: Nginx runs as non-root user `nodejs:nodejs`, requires proper permissions
406
414
-**Build failures**: Run `pnpm clean` then `pnpm install` to reset
407
415
-**Turborepo cache issues**: Delete `.turbo` directory to clear cache
0 commit comments