Skip to content

Live dashboard updates over SSE instead of 5-second polling #29

Description

@xerhab

Context

index.html re-fetches /api/agents every 5s and re-renders the whole tree from innerHTML; history.html polls every 30s. Considerable machinery exists purely to survive the re-render churn: module-level confirming/openLogs/collapsedRepos stores, the optimistic pending map with TTLs, and reconcilePending().

Problem

  • Up to 5s of extra staleness stacked on top of the ~20s heartbeat interval; with the low-latency command work (tunnel poke issue) the heartbeat side gets fast, making UI polling the remaining lag.
  • Full-tree innerHTML re-render every 5s: focus/selection inside anything interactive is lost, open <details> must be tracked manually, and phones burn battery re-fetching an unchanged payload.
  • Polling cost is per-open-tab; leaving the dashboard open on a wall tablet or a phone multiplies it.

Proposal

  • Server-Sent Events (GET /api/events): the hub pushes a data: frame whenever an agent's heartbeat lands, a command is queued/acked, or the offline sweep flips a host — all points already centralized in server.js. SSE beats a WebSocket here: it's plain HTTP (rides the existing basic-auth + Cloudflare tunnel with zero new handshake code — notable since the WS server framing in this codebase is hand-rolled), auto-reconnects natively via EventSource, and the hub never needs data from the browser.
  • Frames can carry the same shape as /api/agents (simplest: full snapshot, letting the client stay dumb) with the initial page load still fetching once; a retry: hint plus falling back to today's polling when EventSource errors keeps it robust.
  • Client: replace setInterval(refresh, 5000) with an EventSource handler feeding the existing render(cache). Optionally follow up with keyed/partial DOM updates to stop the full-tree rebuild — worth doing once updates become event-driven and bursty.
  • Heartbeat cadence note: a Cloudflare-proxied SSE stream needs a keepalive comment every ~30s to survive idle timeouts (the hub already pings its tunnel WSs for the same reason).

Touchpoints

  • agent-hub/server.js — event fan-out, /api/events
  • agent-hub/public/index.html, history.html — EventSource client, polling fallback

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions