import type { Logger } from "@atbb/logger"; /** * Implements circuit breaker pattern to prevent cascading failures. * * Tracks consecutive errors and triggers a callback when threshold is exceeded. * This prevents the system from repeatedly attempting operations that are likely * to fail, allowing for graceful degradation. */ export class CircuitBreaker { private consecutiveFailures = 0; /** * @param maxFailures - Maximum consecutive failures before circuit breaks * @param onBreak - Callback invoked when circuit breaks */ constructor( private maxFailures: number, private onBreak: () => Promise, private logger: Logger ) {} /** * Execute an operation with circuit breaker protection * * @param operation - The async operation to execute * @param operationName - Name for logging purposes */ async execute( operation: () => Promise, operationName: string ): Promise { try { await operation(); this.reset(); } catch (error) { await this.recordFailure(operationName, error); } } /** * Record a failure and check if circuit should break */ private async recordFailure(operationName: string, error: unknown): Promise { this.consecutiveFailures++; this.logger.error("Circuit breaker failure", { operationName, consecutiveFailures: this.consecutiveFailures, maxFailures: this.maxFailures, error: error instanceof Error ? error.message : String(error), }); if (this.consecutiveFailures >= this.maxFailures) { this.logger.error("Circuit breaker tripped - max consecutive failures reached", { maxFailures: this.maxFailures, }); await this.onBreak(); } } /** * Reset the failure counter (call on successful operation) */ reset(): void { this.consecutiveFailures = 0; } /** * Get current failure count for monitoring */ getFailureCount(): number { return this.consecutiveFailures; } }