Real-time Updates
The Mantis dashboard uses Server-Sent Events (SSE) for live updates without page refresh.
How SSE Works
Section titled “How SSE Works”Connection Flow
Section titled “Connection Flow”Event Format
Section titled “Event Format”Data updates are sent as unnamed SSE messages (default message event); the
event type is carried inside the JSON payload, not in an SSE event: field. Use
onmessage (not addEventListener('created', …) for data events) and switch on
payload.type and payload.resource_type. The only named SSE events are the
connected handshake and lagged (buffer-overflow) control events.
: data updates — unnamed (default "message") events, type is inside the payloaddata: {"type":"updated","resource_type":"deployments","resource_id":"abc123","data":{...},...}
data: {"type":"updated","resource_type":"targets","resource_id":"def456","data":{...},...}
: control events are namedevent: connecteddata: {}Connection States
Section titled “Connection States”The dashboard shows connection status:
| State | Badge | Description |
|---|---|---|
| Connected | 🟢 Live | Receiving real-time updates |
| Connecting / Reconnecting | 🟡 Connecting… | Establishing or re-establishing connection |
| Disconnected / Failed | (none) | No live updates |
Both the connecting and reconnecting states show the same Connecting… badge.
Once the client exhausts all retry attempts the state becomes failed, which also
shows no badge — use the manual refresh button to get the latest data.
┌─────────────────────────────────────────────────────────────┐│ Dashboard Period: [Last 7 Days ▼] 🟢 Live [🔄] │├─────────────────────────────────────────────────────────────┤│ ││ Statistics update automatically when changes occur ││ │└─────────────────────────────────────────────────────────────┘Event Types
Section titled “Event Types”All SSE data events share a common envelope. The type field is always one of the
generic CRUD operations; the resource_type field identifies the entity kind.
type | Meaning |
|---|---|
created | A new entity was created |
updated | An existing entity was changed |
deleted | An entity was removed |
The only named (non-message) SSE events are the connected handshake and
lagged (buffer-overflow) control events — listen for those with
addEventListener('connected', …) / addEventListener('lagged', …).
Common Event Payload
Section titled “Common Event Payload”{ "type": "updated", "resource_type": "deployments", "resource_id": "abc123", "data": { ... }, "tenant_id": "tenant-uuid-or-null", "changed_fields": ["status", "progress"], "timestamp": "2024-01-21T14:30:00Z"}resource_type values include statistics, tenant_statistics, deployments,
targets, environments, solutions, actions, sequences, registrations,
freezes, tags, users, roles, tenants, certificates, storage_sources,
identity_providers, thorax_instances, failure_patterns, and
failure_pattern_stats.
Use onmessage and switch on event.data.type plus event.data.resource_type
to identify the change.
Subscription Management
Section titled “Subscription Management”Automatic Subscription
Section titled “Automatic Subscription”The dashboard automatically subscribes on mount:
┌─────────────────────────────────────────────────────────────┐│ Page Load Flow │├─────────────────────────────────────────────────────────────┤│ ││ 1. Dashboard component mounts ││ 2. Load initial statistics via REST API ││ 3. Open SSE connection for live updates ││ 4. Display connection status ││ 5. Receive and apply incremental updates ││ │└─────────────────────────────────────────────────────────────┘Cleanup
Section titled “Cleanup”Connections are properly closed:
| Trigger | Action |
|---|---|
| Navigate away | Unsubscribe from SSE |
| Component unmount | Close connection |
| Logout | Terminate all subscriptions |
| Tab hidden | Optionally pause (future) |
Handling Connection Issues
Section titled “Handling Connection Issues”Automatic Reconnection
Section titled “Automatic Reconnection”The SSE client automatically reconnects:
Backoff Strategy
Section titled “Backoff Strategy”The delay before each retry is
min(initialRetryDelay * 2^attempt, maxRetryDelay) + jitter, where
initialRetryDelay is 1 second, maxRetryDelay caps at 30 seconds, and jitter
is a random value in [0, 1000 ms] added to prevent thundering-herd reconnects. The
client makes up to 10 reconnection attempts by default.
The table below shows the base delay before jitter; actual delays will be up to 1 second longer.
| Attempt | Base Delay | Actual Range |
|---|---|---|
| 1 | 1 second | 1–2s |
| 2 | 2 seconds | 2–3s |
| 3 | 4 seconds | 4–5s |
| 4 | 8 seconds | 8–9s |
| 5 | 16 seconds | 16–17s |
| 6+ | 30 seconds (max) | 30–31s |
Lag Detection
Section titled “Lag Detection”If events are missed during disconnection:
┌─────────────────────────────────────────────────────────────┐│ SSE Lag Handler │├─────────────────────────────────────────────────────────────┤│ ││ 1. Detect missed events (sequence gap) ││ 2. Log warning: "Missed X events" ││ 3. Trigger full data refresh ││ 4. Resume normal event processing ││ │└─────────────────────────────────────────────────────────────┘Global vs Tenant Updates
Section titled “Global vs Tenant Updates”Global Statistics
Section titled “Global Statistics”Administrators receive updates for all tenants:
| Filter | Events Received |
|---|---|
tenant_id: null | Global aggregates |
| No filter | All tenant events |
Tenant Statistics
Section titled “Tenant Statistics”Regular users receive updates for their tenant only:
| Filter | Events Received |
|---|---|
tenant_id: "abc123" | Specific tenant |
| Own tenant only | Scoped updates |
UI Update Patterns
Section titled “UI Update Patterns”Optimistic Updates
Section titled “Optimistic Updates”Statistics cards update immediately:
Before Event:┌───────────┐│ Succeeded ││ 142 │└───────────┘
Event Received: type=updated, resource_type=statistics
After Event:┌───────────┐│ Succeeded ││ 143 │ ← Incremented└───────────┘Trend Chart Updates
Section titled “Trend Chart Updates”The trend chart updates on significant changes:
| Update Trigger | Action |
|---|---|
| New day | Add new data point |
| Deployment completed | Update today’s count |
| Period change | Reload full trend |
Activity Feed Updates
Section titled “Activity Feed Updates”New activities prepend to the list:
┌───────────────────────────────────────────────────────────┐│ Recent Activity │├───────────────────────────────────────────────────────────┤│ ││ ● Just now Deployment succeeded ← NEW ││ web-app v1.2.4 → web-prod-02 ││ ││ ● 2 min ago Deployment succeeded ││ web-app v1.2.3 → web-prod-01 ││ ││ ● 15 min ago Target registered ││ api-staging-02 came online ││ │└───────────────────────────────────────────────────────────┘Target Health Updates
Section titled “Target Health Updates”Status Transitions
Section titled “Status Transitions”Real-time target status changes:
The thresholds are server-side defaults: 90 seconds for Online→Stale and 5 minutes
(300 seconds) for Stale→Offline. They can be overridden via the session.heartbeat_timeout_secs and
session.stale_timeout_secs keys in the [session] block of the Thorax
configuration file (file-only; no THORAX__SESSION__* env vars are recognized).
Health Card Updates
Section titled “Health Card Updates”Target health counts update live:
Event: type=updated, resource_type=targets, data.status="stale"
Before:┌──────────┬──────────┬──────────┬──────────┐│ Total │ Online │ Stale │ Offline ││ 24 │ 21 │ 1 │ 2 │└──────────┴──────────┴──────────┴──────────┘
After:┌──────────┬──────────┬──────────┬──────────┐│ Total │ Online │ Stale │ Offline ││ 24 │ 20 │ 2 │ 2 │└──────────┴──────────┴──────────┴──────────┘Performance Considerations
Section titled “Performance Considerations”The SSE stream has no server-side event throttling and no client-side event-rate
limiting or event-history cap. The server holds up to 1024 events per resource type
in its broadcast buffer (CHANNEL_CAPACITY); a client that falls behind is dropped
and must reconnect. The only client-side debounce is a 200ms coalescing of network
topology rebuilds (specific to the topology view), not the general event stream.
Connections are released on navigation.
Browser Support
Section titled “Browser Support”SSE Compatibility
Section titled “SSE Compatibility”| Browser | SSE Support | Notes |
|---|---|---|
| Chrome | ✅ Full | Native EventSource |
| Firefox | ✅ Full | Native EventSource |
| Safari | ✅ Full | Native EventSource |
| Edge | ✅ Full | Native EventSource |
Fallback Behavior
Section titled “Fallback Behavior”If SSE is unavailable:
┌─────────────────────────────────────────────────────────────┐│ Fallback: Manual Refresh │├─────────────────────────────────────────────────────────────┤│ ││ • SSE connection failed ││ • Live badge not shown ││ • Use refresh button for updates ││ • Consider polling implementation (future) ││ │└─────────────────────────────────────────────────────────────┘Debugging SSE
Section titled “Debugging SSE”Browser DevTools
Section titled “Browser DevTools”Monitor SSE in Network tab:
- Open DevTools (F12)
- Go to Network tab
- Filter by “EventSource” or “sse”
- Click connection to see events
Name Status Type Size/api/v1/sse/statistics 200 eventsource streaming
EventStream:- message 14:30:00 {"type":"updated","resource_type":"statistics",...}- message 14:30:15 {"type":"created","resource_type":"deployments",...}- message 14:30:20 {"type":"updated","resource_type":"deployments",...}Console Logging
Section titled “Console Logging”The SSE client logs connection events:
// Connection establishedSSE: Connected to /api/v1/sse/statistics
// Event receivedSSE: Received updated/statistics event
// Connection lostSSE: Connection lost, reconnecting in 2s...
// Lag detectedSSE: Lagged, missed 5 events. Refreshing data...Common Issues
Section titled “Common Issues”| Issue | Symptom | Solution |
|---|---|---|
| Connection refused | No live badge | Check API availability |
| Events not updating | Stale data | Verify subscription |
| Frequent reconnects | Flashing badge | Check network stability |
| Memory growth | Browser slowdown | Refresh page |
Security
Section titled “Security”Authentication
Section titled “Authentication”SSE connections use a short-lived, single-use token passed in the ?sse_token=
query parameter (not the regular JWT Authorization header, which EventSource
cannot set). Obtain the token via POST /api/v1/auth/sse-token:
GET /api/v1/sse/{resource_type}?sse_token=eyJhbG...Valid resource_type values include statistics, deployments, targets,
environments, solutions, and others. See the API
Authentication guide for the full token flow.
Tenant Isolation
Section titled “Tenant Isolation”Events are filtered by tenant:
| Role | Events Visible |
|---|---|
| Admin | All tenants |
| User | Own tenant only |
Connection Limits
Section titled “Connection Limits”The current implementation enforces no per-user connection cap and no idle timeout.
The server sends an SSE keepalive comment every 3 seconds (SSE_KEEPALIVE_SECS) to
keep connections (and intermediate proxies) from timing out.
Best Practices
Section titled “Best Practices”1. Monitor Connection Status
Section titled “1. Monitor Connection Status”Always check the live indicator:
| Indicator | Meaning |
|---|---|
| 🟢 Live | Updates are automatic |
| 🟡 Connecting | Wait for connection |
| (none) | Use manual refresh |
2. Refresh After Long Absence
Section titled “2. Refresh After Long Absence”If browser was inactive:
- Check connection status
- Click refresh button
- Verify data is current
3. Handle Multiple Tabs
Section titled “3. Handle Multiple Tabs”Each tab maintains its own connection:
- Close unused tabs
- Consider single-tab usage for dashboards
- Browser may throttle background tabs
4. Trust but Verify
Section titled “4. Trust but Verify”For critical decisions:
- Note the live indicator
- Click refresh for certainty
- Check timestamp on data
Troubleshooting
Section titled “Troubleshooting”Live Updates Not Working
Section titled “Live Updates Not Working”Cause: SSE connection failed
Solution:
- Check browser console for errors
- Verify network connectivity
- Check API server health
- Clear browser cache
Data Out of Sync
Section titled “Data Out of Sync”Cause: Missed events during reconnection
Solution:
- Click manual refresh
- Check connection status
- Verify no proxy interference
High CPU Usage
Section titled “High CPU Usage”Cause: Too many events or memory leak
Solution:
- Refresh the page
- Close other tabs
- Check event frequency
Next Steps
Section titled “Next Steps”- Dashboard Overview - Dashboard features
- Statistics - Detailed metrics
- Deployments - Live deployment monitoring
