- 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
63 lines
1.4 KiB
JavaScript
63 lines
1.4 KiB
JavaScript
// Circuit breaker implementation for API resilience
|
|
class CircuitBreaker {
|
|
constructor(failureThreshold = 5, resetTimeout = 60000, errorFilter = null) {
|
|
this.failureThreshold = failureThreshold;
|
|
this.resetTimeout = resetTimeout;
|
|
this.errorFilter = errorFilter;
|
|
this.failureCount = 0;
|
|
this.lastFailureTime = null;
|
|
this.state = 'closed'; // closed, open, half-open
|
|
}
|
|
|
|
async execute(fn, fallback = null) {
|
|
if (this.state === 'open') {
|
|
if (Date.now() - this.lastFailureTime > this.resetTimeout) {
|
|
this.state = 'half-open';
|
|
} else {
|
|
if (fallback) return fallback();
|
|
throw new Error('Circuit breaker is open');
|
|
}
|
|
}
|
|
|
|
try {
|
|
const result = await fn();
|
|
if (this.state === 'half-open') {
|
|
this.close();
|
|
}
|
|
return result;
|
|
} catch (error) {
|
|
if (this.errorFilter && !this.errorFilter(error)) {
|
|
throw error;
|
|
}
|
|
|
|
this.failureCount++;
|
|
this.lastFailureTime = Date.now();
|
|
|
|
if (this.failureCount >= this.failureThreshold) {
|
|
this.open();
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
close() {
|
|
this.failureCount = 0;
|
|
this.state = 'closed';
|
|
}
|
|
|
|
open() {
|
|
this.state = 'open';
|
|
}
|
|
|
|
getState() {
|
|
return {
|
|
state: this.state,
|
|
failureCount: this.failureCount,
|
|
lastFailureTime: this.lastFailureTime
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = CircuitBreaker;
|