fix(realtime): drop redundant 2s meeting poll already covered by realtime#103
fix(realtime): drop redundant 2s meeting poll already covered by realtime#103pratikbodkhe wants to merge 1 commit into
Conversation
…time useMeetingRealtime opened a Supabase realtime channel on postgres_changes for meetings, issues, and decisions, then also ran setInterval(refreshMeeting, 2000). The timer re-invalidated five query keys every two seconds, producing a storm of REST refetches on every open meeting page (visible as endless repeating meetings/issues/meeting_series/series_participants requests in the network tab). All three tables are already in the supabase_realtime publication with REPLICA IDENTITY FULL (20260531140000_realtime_series_participants.sql), so realtime delivers every change the poll was catching. Remove the interval; keep the channel. Add a regression test asserting an idle meeting page issues no timer-driven /rest/v1/meetings refetches.
|
Closing: the 2s poll is load-bearing, not redundant. The meeting page renders issues/decisions from the denormalized meeting.issues (the useMeeting detail query), which the optimistic issue mutations do not update (they touch the ["issues",*] list caches) and which onSettled invalidates with refetchType:'inactive' (no active refetch). The 2s poll was the only thing keeping meeting.issues fresh on an open meeting page; realtime is not reliably refetching it in this environment. Removing the poll regressed same-client (meeting-resolution-flow:51) and cross-client (realtime-collaboration:255) meeting-page updates across 3 CI runs (last one on a clean, non-rate-limited stack). Keeping the poll. The request-volume concern can be revisited once realtime delivery is verified in the self-host stack. |
Problem
Every open meeting page fired a storm of repeated REST requests every 2 seconds:
meetings,issues,meeting_series,series_participants, plus an authusercheck. On a long-lived tab this accumulated tens of thousands of requests.Root cause
useMeetingRealtime(src/lib/hooks/use-meetings.ts) already opens a Supabase realtime channel subscribing topostgres_changesonmeetings,issues, anddecisions, all routed to the samerefreshMeeting. It also ransetInterval(refreshMeeting, 2000), which re-invalidated five React Query keys (meeting detail, meeting list, issues list, decisions, series detail) on a timer regardless of whether anything changed. The poll was a fallback that became dead weight once realtime landed, but it was never removed.Fix
Remove the interval and its teardown; keep the realtime channel. The three subscribed tables are in the
supabase_realtimepublication withREPLICA IDENTITY FULL(20260531140000_realtime_series_participants.sql), so realtime already delivers every change the poll was catching.Net: event-driven refresh replaces a 5-key-invalidation REST storm every 2s. No functional regression. The only behavioral delta is a series rename mid-meeting no longer auto-refreshing the breadcrumb, which self-heals on refetch-on-focus or navigation and does not affect meeting collaboration.
Tests
Added a regression test in
e2e/regression/realtime-collaboration.spec.tsasserting an idle meeting page issues no timer-driven/rest/v1/meetingsrefetches in a 5s window (the old poll produced several). Existing realtime collaboration tests already prove cross-client propagation works without polling.Verification
tsc --noEmit: no new type errors from this changeeslint: clean on both changed filesgitnexus impact: LOW risk, single callerMeetingDetailContent, behaviorally transparentpnpm test:oss-boundaries: passNote: full local E2E could not run because Docker/Supabase local was down on this machine. The full suite runs in CI across shards on this PR and is the merge gate.