Skip to content

feat: auto-reconnect and rejoin line after manager restart - #736

Merged
birme merged 2 commits into
mainfrom
frontend/505-manager-restart-reconnect
Oct 16, 2026
Merged

birme merged 2 commits into
mainfrom
frontend/505-manager-restart-reconnect

Conversation

@birme

@birme birme commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Classify heartbeat outcomes as unreachable (network / 5xx / 429) vs lost (404/410), and stop the heartbeat loop once a session is lost instead of retrying a dead session forever.
  • Add a session-recovery hook that shows a "Reconnecting…" banner while the manager is unreachable and automatically rejoins the line (new session + offer + peer connection) when the session is lost or the peer connection drops after having connected.
  • Retry rejoin setup with backoff (2s→10s); after 60s without recovery, surface an error banner with a manual Rejoin button; clear automatically if the manager recovers on its own.
  • Backend already persists user sessions in the DB (saveUserSession/getSessionsByQuery) and audio flows client↔SMB, so restart recovery needed only the frontend reconnect/UI layer — no manager change required.

Test plan

  • Tests pass (npm test) — 46 files / 376 tests
  • TypeScript compiles (npm run typecheck)
  • Lint clean (npm run lint)
  • Manual: restart intercom-manager mid-call and confirm clients show the reconnecting state, auto-rejoin their lines, and get the manual Rejoin fallback after the retry window

Closes #505

🤖 Generated with Claude Code

Heartbeat now classifies unreachable (network/5xx) vs lost (404/410)
sessions. A recovery hook shows a reconnecting banner, automatically
rejoins when the session is lost or the peer connection fails, retries
session setup with backoff, and after 60s offers a manual Rejoin.

Closes #505

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@birme

birme commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

code-reviewer verdict: NEEDS_CHANGES (self-authored PR — recorded as a marker since GitHub blocks state-bearing self-review by the authoring account). Reviewed commit 9501355.

Blocking

  1. A peer-connection failure permanently hides the call UI even after a successful rejoin. useIsLoading sets connectionError = true on "failed" and never resets it, and production-line.tsx renders CallContainer only when !connectionError. The connectionLost auto-rejoin then succeeds in the hook, but the user is left with a blank screen. Fix: reset connectionError when connectionState becomes connected/null, or stop treating post-everConnected failed as terminal. No test covers this.
  2. Auto-rejoin has no backoff for repeated session loss / peer failure. failureCount is only incremented by reportEstablishError, so a session that is created then ends lost/failed rejoins with a 0ms delay every cycle (create+delete session and peer connection unthrottled) until the 60s window. Fix: increment failureCount in the rejoin path and reset only on a confirmed connected; add a test for repeated lost/failed.

Should-fix
3. use-session-recovery.ts: refs (everConnected.current, onRejoinRef.current) are written during render — unsafe under concurrent/StrictMode renders; move into effects.
4. production-line.tsx: onEstablishError is only wired when connectionAttempt > 0, so a first-attempt establish failure still takes the old fatal ERROR path — confirm/comment the asymmetry.
5. Test gaps: no test that the heartbeat loop stops after lost; none for 404/429 classification; none for useEstablishSession onError/retry reset; no ProductionLine wiring test (key remount, rejoin reset, stale-connected guard).

Moving the board item back to Ready for a follow-up pass to address the two blocking items.

Address code review NEEDS_CHANGES on the manager-restart auto-reconnect
flow:

- useIsLoading now clears connectionError when connectionState becomes
  "connected" or null, so a successful auto-rejoin restores the call UI
  instead of leaving a blank screen (a post-everConnected "failed" was
  treated as terminal).
- useSessionRecovery increments failureCount in the automatic rejoin
  path so repeated session loss / peer failure back off instead of
  churning create+delete session/peer connections at 0ms every cycle;
  the count still resets only on a confirmed "connected" (or manual
  rejoin).
- Move ref writes (onRejoinRef, everConnected) out of render and into
  effects to be safe under concurrent/StrictMode renders.
- Document the first-attempt vs rejoin onEstablishError asymmetry in
  production-line.

Tests: add useIsLoading coverage (error reset on reconnect/null),
repeated lost/failed backoff and backoff-reset cases in
useSessionRecovery, and 404/429 heartbeat classification.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@birme

birme commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

code-reviewer verdict: LGTM (self-authored PR — recorded as a marker since GitHub blocks state-bearing self-review by the authoring account). Re-reviewed commit 79644fd.

All five prior NEEDS_CHANGES items verified genuinely fixed (connectionError reset on reconnect; failureCount backoff in the rejoin path with reset only on confirmed connect; refs moved into effects; onEstablishError asymmetry documented; 404/429 heartbeat classification tests). Build health on a clean npm ci: typecheck PASS, lint PASS (0 warnings under --max-warnings 0), tests PASS 386/386 across 47 files. Logic traced by hand for off-by-one / missing-reset / StrictMode races — holds up.

Two minor optional suggestions (non-blocking): dedupe/offset stacked ReconnectBanners when multiple lines degrade at once; optionally move the latest-ref-in-render pattern in use-heartbeat.ts / use-establish-session.ts into effects for consistency. Neither blocks merge.

@birme
birme merged commit 5569ccb into main Oct 16, 2026
6 checks passed
@birme
birme deleted the frontend/505-manager-restart-reconnect branch October 16, 2026 13:49
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.

Manager: Test restarting the manager when calls are active

2 participants