Telegram (ask questions / claim the issue here first): https://t.me/+DOylgFv1jyJlNzM0
Labels: bug, frontend, Stellar Wave
useStreamEvents reopens the EventSource on every render, and since every incoming event re-renders the consumer, the stream ends up reconnecting on every event.
Look at frontend/src/hooks/useStreamEvents.ts:47-64. buildUrl is a useCallback that depends on streamIds, but the default is streamIds = [] (a fresh array each render) and every call site passes an inline array literal. New array identity means new buildUrl, which means new connect, which trips the mount effect (deps [connect]) into tearing down and recreating the EventSource. Then each event fires setEvents, re-renders the consumer, and the whole thing goes around again. It's a self-sustaining reconnect loop that leaks connections.
What the fix has to hold to
- Subscription identity is stable: derive a string key from
streamIds/subscribeToAll/jwtToken so connect/buildUrl only change when the subscription actually changes
- One EventSource per distinct subscription, not per render and not per event
- Clear any pending reconnect timer before scheduling a new one, and cap reconnect attempts
Done when
Where to start
Fix is in useStreamEvents.ts; the call sites passing inline arrays are NotificationDropdown.tsx, dashboard/dashboard-view.tsx, and app/streams/[id]/page.tsx. Backend SSE controller is out of scope. Smallish change once the stable-key approach is in place.
Labels:
bug,frontend,Stellar WaveuseStreamEventsreopens the EventSource on every render, and since every incoming event re-renders the consumer, the stream ends up reconnecting on every event.Look at
frontend/src/hooks/useStreamEvents.ts:47-64.buildUrlis auseCallbackthat depends onstreamIds, but the default isstreamIds = [](a fresh array each render) and every call site passes an inline array literal. New array identity means newbuildUrl, which means newconnect, which trips the mount effect (deps[connect]) into tearing down and recreating the EventSource. Then each event firessetEvents, re-renders the consumer, and the whole thing goes around again. It's a self-sustaining reconnect loop that leaks connections.What the fix has to hold to
streamIds/subscribeToAll/jwtTokensoconnect/buildUrlonly change when the subscription actually changesDone when
Where to start
Fix is in
useStreamEvents.ts; the call sites passing inline arrays areNotificationDropdown.tsx,dashboard/dashboard-view.tsx, andapp/streams/[id]/page.tsx. Backend SSE controller is out of scope. Smallish change once the stable-key approach is in place.