Skip to content

Show TUI connection status - #273

Open
robzolkos wants to merge 2 commits into
mainfrom
offline-notice
Open

Show TUI connection status#273
robzolkos wants to merge 2 commits into
mainfrom
offline-notice

Conversation

@robzolkos

@robzolkos robzolkos commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • show one persistent connection-status row across Mail, Contacts, Calendar, and Journal while the TUI is offline or Action Cable is reconnecting
  • clear the row after reconnecting and catch up the visible mail box so broadcasts missed during the gap are reflected
  • bound initial cable dials, retry network/terminal failures with capped backoff, preserve authentication failures without looping, and keep the shared cable connection owned by the TUI rather than a replaceable Screener subscription
  • coalesce box doorbells under load while prioritizing connection transitions, and close clients whose initial dial never acquires an owner

Verification

  • GOWORK=off make check
  • GOWORK=off make race-test
  • GOWORK=off make coverage — 82.7% repository coverage
  • GOWORK=off make test-e2e — 177 checks passed
  • govulncheck ./... — no called vulnerabilities
  • gitleaks detect --source . --verbose --redact — no leaks
  • controlled live TUI exercise against real HEY data: connected → cable unavailable → visible reconnecting status → automatic reconnect → status removed and box caught up

Demo

TUI disconnect and reconnect

Basecamp: https://app.basecamp.com/2914079/buckets/48521764/card_tables/cards/10225695892


Summary by cubic

Show a standing TUI connection status and make live updates resilient across sections. Previously only Mail showed “Not live” after disconnect; now the app shows Offline/Reconnecting globally, retries on network failures, and catches up the visible box on reconnect.

  • Render a global status row under the header in Mail, Contacts, Calendar, and Journal. Show “Offline — reconnecting to HEY”, “Live updates disconnected — reconnecting to HEY”, or “Live updates unavailable,” clear it on reconnect, and re-read the visible box via tui.AnyBoxChanged.
  • Replace box-only notifications with tui.MailWatchEvent (box or connection). Prioritize connection transitions over box doorbells; coalesce a full backlog into a single catch-up; drain stale doorbells; ignore stale retry timers once connected.
  • Retry network failures with capped exponential backoff (2s–30s). Keep classified errors (e.g., auth) as “Live updates unavailable.”
  • Bound the initial Action Cable dial (tuiCableDialTimeout = 5s). Ensure cable.Dial closes clients on connect failure to stop background retries.
  • Share one actioncable.Client across subscriptions and replace it when stopped (actioncable.ErrClosed or terminal DisconnectError{Reconnect:false}). Give Screener subscriptions a short-lived context so replacing a signed stream unsubscribes without closing Mail’s shared connection.
  • Guard channel lifecycles: the relay is the only writer to streams it closes, safely drains queued callbacks, and avoids blocking Action Cable callbacks.
  • Docs updated and tests added for connection state, client replacement, retry scheduling, error sanitization, and backlog coalescing.

Required updates

  • tui.MailWatcher now returns <-chan tui.MailWatchEvent instead of box IDs.
  • tui.ScreenerWatcher now takes two contexts: (ctx, connectionCtx context.Context, signedStreamName string).

Written for commit 0309b80. Summary will update on new commits.

Review in cubic

@robzolkos
robzolkos requested a review from a team as a code owner August 22, 2026 10:43
Copilot AI balanced review requested due to automatic review settings August 22, 2026 10:43

Copilot AI 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.

Pull request overview

Adds resilient, app-wide TUI connection status and Action Cable reconnection handling.

Changes:

  • Shows persistent offline/reconnecting status across all TUI sections.
  • Adds bounded retries, reconnection catch-up, and shared cable ownership.
  • Prioritizes connection events and expands lifecycle/error tests.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
README.md Documents automatic reconnection and status display.
AGENTS.md Updates TUI live-update architecture guidance.
internal/tui/tui.go Integrates global connection state and catch-up handling.
internal/tui/mail.go Removes mail-only connection notices.
internal/tui/live.go Defines events, statuses, and retry behavior.
internal/tui/errors.go Preserves classified API errors.
internal/tui/live_test.go Tests status, retry, and watcher behavior.
internal/tui/screener_test.go Tests classified error messages.
internal/cmd/tui_watch.go Relays connection events and manages shared cable clients.
internal/cmd/tui_watch_test.go Tests event priority and client replacement.
internal/cable/cable.go Closes failed dial clients.
internal/cable/cable_test.go Verifies failed dials stop retrying.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/cmd/tui_watch.go
@robzolkos
robzolkos requested a review from monorkin August 22, 2026 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants