feat(sessions): add real-time session updates via server-sent events#3868
feat(sessions): add real-time session updates via server-sent events#3868Lokimorty wants to merge 2 commits intoumami-software:masterfrom
Conversation
Implements push-based real-time updates for the Sessions page. New sessions now appear instantly without manual reload or polling. Changes: - Add SSE event emitter for session creation notifications - Create SSE stream endpoint at /api/websites/[id]/sessions/stream - Emit session events in tracking endpoint when sessions are created - Add useSessionStream hook to connect to SSE and invalidate queries - Fix LoadingPanel to prevent flicker during background refetches
|
@Lokimorty is attempting to deploy a commit to the umami-software Team on Vercel. A member of the Team first needs to authorize it. |
Improvements: - Add Redis pub/sub support for multi-server deployments - Add authentication check to SSE stream endpoint - Add 30s heartbeat keepalive for long-lived connections - Implement exponential backoff reconnection logic in client - Fix TypeScript types (websiteId optional, timer types) - Use specific query key invalidation instead of broad match - Fix undefined access in session-events listener map
Greptile OverviewGreptile SummaryImplemented real-time session updates using Server-Sent Events with in-memory pub/sub pattern. When new sessions are created via
Critical Issue: SSE endpoint missing authentication - any unauthenticated user can access session data streams Confidence Score: 1/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Client as Browser Client
participant UI as SessionsDataTable
participant Hook as useSessionStream
participant SSE as /sessions/stream
participant Events as session-events.ts
participant Track as /api/send
participant DB as Database
Client->>UI: Navigate to sessions page
UI->>Hook: Initialize useSessionStream(websiteId)
Hook->>SSE: GET /api/websites/{websiteId}/sessions/stream
SSE->>Events: subscribeToSessions(websiteId, callback)
Events-->>SSE: return unsubscribe function
SSE-->>Hook: SSE connection established
Note over Client,Track: User visits tracked website
Client->>Track: POST /api/send (tracking event)
Track->>DB: createSession(sessionData)
DB-->>Track: session created
Track->>Events: emitSessionCreated(websiteId, sessionId)
Events->>SSE: invoke listener callback
SSE->>Hook: SSE message with sessionId
Hook->>UI: queryClient.invalidateQueries(['sessions'])
UI->>DB: refetch sessions data
DB-->>UI: updated sessions list
UI->>Client: display new session
Client->>UI: Navigate away
Hook->>SSE: EventSource.close()
SSE->>Events: unsubscribe()
|
There was a problem hiding this comment.
Additional Comments (3)
-
src/app/api/websites/[websiteId]/sessions/stream/route.ts, line 3-7 (link)logic: missing authentication and authorization - endpoint allows anyone to stream session updates without verifying they have permission to view this website
-
src/lib/session-events.ts, line 11-13 (link)logic: empty listener sets are never cleaned up from memory
-
src/components/hooks/useSessionStream.ts, line 10-14 (link)style: missing error handling - connection failures, network issues, or server errors will silently fail without retry or notification
7 files reviewed, 3 comments
|
Authentication: Added the missing parseRequest() and canViewWebsite() checks to the SSE endpoint. Now it properly validates permissions before streaming any session data (see stream/route.ts:12-22) Memory leak: Fixed the listener cleanup logic. Empty sets are now removed from the map when the last listener unsubscribes (session-events.ts:18-20) Error handling: Added try/catch blocks around JSON parsing with proper error logging (useSessionStream.ts:30-33) Reconnection: Implemented exponential backoff that starts at 1s and caps at 30s (useSessionStream.ts:41-47) |
|
This is really nice, but the problem is that it won't work on Vercel or any other providers that use serverless to handle requests. |
|
I can see a few ways we can make it work:
and cost money, I think it's about the same with 200k messages/day = free, $50/1m messages, but creates external dependency. Self-hosting will probably have no real-time updates because of it (it'll just stay same as now)
I'm thinking the first makes most sense, it covers both self-hosted and serverless without external dependencies |
Summary
Implements push-based real-time updates for the Sessions page using Server-Sent Events. New sessions now appear instantly without manual reload or polling - updates only happen when actual session creation events occur.
Changes
Notes
This uses in-memory pub/sub, suitable for single-server deployments. Multi-server setups would need Redis pub/sub.