fix(session): WebSocket auto-reconnect with exponential backoff (#18) - #116
fix(session): WebSocket auto-reconnect with exponential backoff (#18)#116ghzhost wants to merge 5 commits into
Conversation
Closes Bitcoindefi#18 Implement automatic reconnection with exponential backoff when the WebSocket connection drops, as described in issue Bitcoindefi#18. - scheduleReconnect(attempt): computes delay (1s, 2s, 4s... up to 30s), shows reconnecting status to the player, and schedules the next attempt - connectSocket(attempt): creates a new WebSocket reusing onopen/onmessage handlers from the original socket instance - Max 6 attempts; after exhaustion shows a clear reload message - Cancels pending reconnect on cleanup (unmount / connection change)
Closes Bitcoindefi#18 - scheduleReconnect: backoff 1s/2s/4s.../30s max, up to 6 attempts - connectSocket: creates new WebSocket reusing existing handlers - Shows reconnecting status to the player between attempts - On exhaustion: clear message to reload the page - Clears pending reconnect timeout on cleanup
…eout React Hooks (useRef) cannot be called inside callbacks or useEffect bodies. The reconnect timeout ID does not need to survive re-renders - it is only used within the single useEffect closure - so a plain `let` variable is correct and lint-clean. Fixes the ESLint error: react-hooks/rules-of-hooks: React Hook "useRef" cannot be called inside a callback
✅ CI Status UpdateFrontend lint is now passing. Fixed ESLint error CI results (latest push
|
| Job | Result |
|---|---|
| Gitar | ✅ success |
| Server (typecheck, lint, build) | ✅ success |
| Frontend (typecheck, lint, build) | ✅ success (lint error fixed) |
| Docker build checks | ✅ success |
| Gitleaks Security Scan | ✅ success |
| API (typecheck, test, build) | ❌ pre-existing failures |
Pre-existing API test failures (not caused by this PR)
market.integration.test.tsfails withENOENT: .../api/src/jsons/npcs.json→ tracked in Falta api/src/jsons/npcs.json en el repositorio y el test de market no puede correr #83platform.integration.test.tsranking endpoint returns 500 → tracked in El endpoint de ranking devuelve 500 en un entorno limpio #84
These failures exist on main branch CI (red since PR #81). This PR introduces no new test failures.
What this PR implements (issue #18)
- Automatic WebSocket reconnect with exponential backoff (
1s → 2s → 4s → … → 30s) - Max 6 retry attempts before asking user to reload
- Visible reconnecting status:
"Reconectando… (intento N/6, en Xs)" - Clean cleanup on
useEffectteardown (no stale timers) - Preserves all original ping/keepalive behavior
|
Pushed commit
|
After a successful WebSocket reconnect, the onerror/onclose handlers
captured the stale reconnectAttempt value from the closure (e.g., 3),
causing subsequent disconnects to schedule reconnects starting at the
wrong attempt number.
Fix: inside ws.onopen (after validating the instance), overwrite
ws.onerror and ws.onclose with fresh closures that call
scheduleReconnect(0), resetting the backoff to the beginning.
Also emit {connected:true, connecting:false} on successful open so the
UI accurately reflects the connected state after a reconnect.
✅ Fix: Reconnect attempt counter now resets after successful connectionPushed commit What was wrong
What changedInside Bonus: All four gitar-bot findings are now addressed. CI should pass. |
CI failed: ESLint failed due to an invalid React Hook call inside a callback in the frontend session hook, and backend integration tests failed due to a missing npcs.json game data file.OverviewTwo distinct failure patterns were identified across the CI jobs: an ESLint error in the frontend build pipeline caused by an improper React Hook call, and backend integration test failures caused by a missing required game data file ( FailuresFrontend ESLint React Hook Violation (confidence: high)
Backend Integration Test Missing Game Data File (confidence: high)
Summary
Code Review ✅ Approved 4 resolved / 4 findingsAdds WebSocket auto-reconnect with exponential backoff and a 6-attempt limit, addressing the useRef hook misuse, stale socket closures, duplicate reconnect scheduling, and unreset attempt counter findings. ✅ 4 resolved✅ Bug: useRef() called inside useEffect throws Invalid hook call
✅ Bug: Reused onopen/onmessage close over stale socket, reconnect fails
✅ Bug: onerror and onclose both schedule reconnect, causing duplicates
✅ Bug: Reconnect attempt counter never resets after success
Tip Comment OptionsAuto-apply is off → Gitar will not commit updates to this branch. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar |
Resumo
Implementa reconexão automática com backoff exponencial quando a conexão WebSocket cai, conforme solicitado na #18.
O que muda
scheduleReconnect(attempt): calcula o delay (1s → 2s → 4s → … → 30s), atualiza o status visível para o jogador ("Reconectando… (intento 1/6, en 2s)") e agenda o próximo intento comsetTimeout.connectSocket(attempt): cria um novoWebSocketreutilizando os handlersonopeneonmessagedo socket original, sem duplicar lógica.useEffect(unmount ou troca de conexão).Critérios de aceitação (do issue)
"reconectando…"com contagem regressiva e número de intentoO que NÃO está neste PR (escopo conservador)
visibilitychange/pagehidelistener (pode ser adicionado em follow-up sem mudar esta lógica)Arquivos
frontend/components/game/session/useGameSession.ts