UNPKG

cachly

Version:

Type-safe, production-ready in-memory cache system for Node.js and TypeScript with advanced features.

98 lines 3.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CircuitBreaker = void 0; class CircuitBreaker { constructor(config) { this.failureCount = 0; this.monitorWindow = []; this.config = config; this.state = { state: 'closed', failureCount: 0, lastFailureTime: 0, nextAttemptTime: 0, }; } async execute(key, operation, fallback) { if (!this.config.enabled) { return operation(); } if (this.state.state === 'open') { if (Date.now() < this.state.nextAttemptTime) { if (fallback) { return fallback(key); } throw new Error(`Circuit breaker is open for key: ${key}`); } this.state.state = 'half-open'; } try { const result = await operation(); this.onSuccess(); return result; } catch (error) { this.onFailure(); if (fallback) { return fallback(key); } throw error; } } onSuccess() { this.failureCount = 0; this.state.failureCount = 0; this.state.state = 'closed'; this.monitorWindow = []; } onFailure() { const now = Date.now(); this.failureCount++; this.state.failureCount = this.failureCount; this.state.lastFailureTime = now; // Add to monitoring window this.monitorWindow.push(now); // Remove old entries from monitoring window const windowSize = this.config.monitorWindow || 60000; // 1 minute default this.monitorWindow = this.monitorWindow.filter(time => now - time < windowSize); if (this.failureCount >= this.config.failureThreshold) { this.state.state = 'open'; this.state.nextAttemptTime = now + this.config.recoveryTimeout; } } getState() { return { ...this.state }; } isOpen() { return this.state.state === 'open'; } isHalfOpen() { return this.state.state === 'half-open'; } isClosed() { return this.state.state === 'closed'; } getFailureCount() { return this.failureCount; } reset() { this.failureCount = 0; this.state = { state: 'closed', failureCount: 0, lastFailureTime: 0, nextAttemptTime: 0, }; this.monitorWindow = []; } getFailureRate() { if (this.monitorWindow.length === 0) return 0; const now = Date.now(); const windowSize = this.config.monitorWindow || 60000; const recentFailures = this.monitorWindow.filter(time => now - time < windowSize).length; return recentFailures / this.monitorWindow.length; } } exports.CircuitBreaker = CircuitBreaker; //# sourceMappingURL=CircuitBreaker.js.map