Replace notification polling with Server-Sent Events (SSE)

Add real-time notification delivery via SSE to replace the 30-second
polling interval. The SSE endpoint streams notification_update,
broadcast_update, and notification_status events to connected clients.

Backend:
- New SSEConnectionManager (lib/galaxy/managers/sse.py) maps user IDs
  to asyncio queues with thread-safe push via call_soon_threadsafe
- SSE streaming endpoint at GET /api/notifications/stream with
  Last-Event-ID catch-up support and 30s keepalive
- Kombu control tasks (notify_users, notify_broadcast) fan out events
  across all Galaxy worker processes
- Existing polling API unchanged for backward compatibility

Frontend:
- New useNotificationSSE composable using EventSource with auto-reconnect
- notificationsStore tries SSE first, falls back to polling after 5+
  consecutive errors

Tests:
- API integration tests for SSE event delivery, broadcasts, and reconnect
- Selenium E2E tests for notification appearance and bell indicator

Add SSE-based real-time history update notifications

Replace aggressive 3-second history polling with Server-Sent Events
driven by database change detection, configurable via admin setting.

Backend:
- Add pg_notify() to PostgreSQL audit triggers for instant LISTEN/NOTIFY
- New HistoryAuditMonitor: PG LISTEN/NOTIFY with SQLite polling fallback
- New /api/events/stream SSE endpoint (uses StructuredApp, not MinimalManagerApp)
- Kombu control task "history_update" with message TTL (expiration=10s)
- Config: enable_sse_history_updates, history_audit_monitor_poll_interval

Frontend:
- Generalize useNotificationSSE → useSSE composable with event type filtering
- historyStore connects SSE for history_update events, triggers immediate refresh
- notificationsStore updated to use /api/events/stream and useSSE
- Polling kept as fallback at existing intervals

Tests:
- 5 integration tests: endpoint, dataset upload event, history ID in payload,
  cross-user isolation, polling backward compatibility
This commit is contained in:
mvdbeek
2026-04-28 15:54:28 +02:00
parent 4ffbe92245
commit 06cdb3a444
21 changed files with 1837 additions and 48 deletions
+28
View File
@@ -5804,6 +5804,34 @@
:Type: str
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``enable_sse_history_updates``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:Description:
Enables real-time history update notifications via Server-Sent
Events (SSE). When enabled, a background monitor watches for
history changes (via PostgreSQL LISTEN/NOTIFY or audit table
polling as a fallback for SQLite) and pushes update signals to
connected browsers, replacing aggressive 3-second polling.
:Default: ``false``
:Type: bool
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``history_audit_monitor_poll_interval``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:Description:
The interval in seconds between history audit table polls when
using the polling fallback (SQLite or when PostgreSQL
LISTEN/NOTIFY is unavailable). Only used when
enable_sse_history_updates is true. Lower values mean faster
updates but more database queries. Recommended range: 1-5 seconds.
:Default: ``2``
:Type: int
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``enable_notification_system``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~