Files
skywatch/server/retryPolicy.js
nmemmert db85573986 feat: Add real-time notification center with WebSocket integration
- Add in-app notification system with database storage
- Implement bell icon component with unread count badge in dashboard header
- Add full Notifications page tab with pagination and filtering (All/Unread/Read)
- Implement real-time WebSocket push notifications to all connected clients
- Add notification API endpoints: GET, PUT /read, DELETE, POST /clear
- Fix critical bug in notificationService where 'status' variable was undefined
- Add Notifications route to App.js routing
- Enhanced UI with notification popup in header and dedicated full-page view
- Auto-reconnect WebSocket with 5s timeout on disconnect
- Support rich notification content with resource details and timestamps
2026-01-14 14:51:29 -05:00

45 lines
1.2 KiB
JavaScript

// Retry logic with exponential backoff
class RetryPolicy {
constructor(maxRetries = 3, initialDelayMs = 1000, maxDelayMs = 10000) {
this.maxRetries = maxRetries;
this.initialDelayMs = initialDelayMs;
this.maxDelayMs = maxDelayMs;
}
async execute(fn, context = 'operation') {
let lastError;
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error;
if (attempt < this.maxRetries) {
const delay = this.calculateBackoff(attempt);
await this.sleep(delay);
}
}
}
const error = new Error(`${context} failed after ${this.maxRetries + 1} attempts`);
error.originalError = lastError;
throw error;
}
calculateBackoff(attempt) {
// Exponential backoff: initialDelay * 2^attempt
// With jitter: ±10%
const exponentialDelay = this.initialDelayMs * Math.pow(2, attempt);
const cappedDelay = Math.min(exponentialDelay, this.maxDelayMs);
const jitter = cappedDelay * 0.1 * (Math.random() - 0.5);
return cappedDelay + jitter;
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
module.exports = RetryPolicy;