Before:
- Dashboard would close after just 1 heartbeat failure (line 405)
if (self.heartbeatFailureCount >= 1)was the threshold
After:
- Increased threshold to 5 failures before taking action
- Configurable via
this.heartbeatMaxFailures = 5 - Shows warning after 2 failures, error after 5 failures
Before:
window.close()was called after single failure (line 407)- Completely killed the UI with no recovery option
After:
- Replaced with user-visible error message
- Shows connection status with visual feedback
- Provides "Retry Now" and "Reload Dashboard" buttons
- Dashboard stays open and functional
Before:
- Heartbeat ran every 250ms (line 391)
- Excessive network overhead and server load
After:
- Increased to 5000ms (5 seconds)
- Configurable via
this.heartbeatInterval = 5000 - Much more reasonable for connection monitoring
Before:
- No timeout on heartbeat AJAX requests
- Could hang indefinitely
After:
- Added 10-second timeout
- Configurable via
this.heartbeatTimeout = 10000 - Prevents hung requests from blocking recovery
Before:
- Single failure = immediate crash
- No attempt to recover connection
After:
- Automatic reconnection with exponential backoff
- Up to 10 reconnection attempts (configurable)
- Backoff formula:
min(2^attempt * 1000ms, 30s) - Example: attempt 1 = 2s, attempt 2 = 4s, attempt 3 = 8s, etc.
- Maximum delay capped at 30 seconds
Before:
- Only console messages
- User had no visibility into connection issues
After:
- Warning banner after 2 failures (yellow)
- Error banner after 5 failures (red)
- Real-time reconnection status updates
- Manual retry option
- Reload dashboard option
showConnectionWarning() // Yellow banner after 2 failures
showConnectionError() // Red banner with retry options
hideConnectionError() // Remove banners when recoveredattemptReconnection() // Smart reconnection with backoff
manualReconnect() // User-triggered retrystartHeartbeat() // Initialize heartbeat monitoring
stopHeartbeat() // Stop heartbeat (if needed)All heartbeat behavior is now configurable via instance variables:
this.heartbeatMaxFailures = 5; // Failures before showing error
this.heartbeatInterval = 5000; // Interval between heartbeats (ms)
this.heartbeatTimeout = 10000; // AJAX request timeout (ms)
this.maxReconnectAttempts = 10; // Max reconnection attempts- 0-1 failures: Silent (logged to console)
- 2 failures: Yellow warning banner appears
- 5+ failures: Red error banner with reconnection status
- Automatic recovery: All banners disappear when connection restored
- Attempt 1: 2 seconds delay
- Attempt 2: 4 seconds delay
- Attempt 3: 8 seconds delay
- Attempt 4: 16 seconds delay
- Attempt 5: 30 seconds delay (capped)
- Attempts 6-10: 30 seconds delay each
Users can now:
- Retry Now: Immediately attempt reconnection (resets backoff)
- Reload Dashboard: Full page reload if all else fails
- Monitor Status: Real-time updates on reconnection progress
- Test normal operation: Verify 5-second heartbeat interval
- Test connection loss: Stop backend server, verify warning/error progression
- Test reconnection: Restart backend, verify automatic recovery
- Test manual retry: Click "Retry Now" button during connection loss
- Test exponential backoff: Verify increasing delays between attempts
- Test max attempts: Verify behavior after 10 failed attempts
C:\codedev\serena-mcp\src\serena\resources\dashboard\dashboard.js- Added 153 lines of improved heartbeat logic
- Total file size: 2120 lines (was 1967 lines)
All changes are fully backward compatible:
- No API changes required
- No HTML changes required
- Works with existing
/heartbeatendpoint - No database or configuration changes needed
Before:
- 4 heartbeat requests per second (250ms interval)
- Immediate crash on any network hiccup
- No recovery mechanism
After:
- 0.2 heartbeat requests per second (5s interval)
- 95% reduction in heartbeat network traffic
- Graceful handling of temporary network issues
- Automatic recovery from failures
- No security vulnerabilities introduced
- Exponential backoff prevents reconnection spam
- Maximum attempt limit prevents infinite loops
- Timeout prevents resource exhaustion
Potential improvements that could be added:
- SSE/WebSocket Support: Replace polling with push notifications
- Configurable UI: Allow users to adjust heartbeat settings
- Health Metrics: Track and display connection quality over time
- Offline Mode: Continue showing cached data during disconnection
- Browser Visibility API: Pause heartbeat when tab is hidden
Date: 2026-01-05 Status: COMPLETE Severity: Critical stability fix Impact: Production-ready heartbeat resilience