@@ -5,12 +5,13 @@ export enum CircuitState {
55}
66
77export interface CircuitBreakerOptions {
8- failureThreshold ?: number ;
9- resetTimeoutMs ?: number ;
8+ failureThreshold ?: number ; // Number of failures before opening
9+ cooldownPeriodMs ?: number ; // Time in ms before attempting half-open
1010}
1111
1212export class CircuitBreakerOpenError extends Error {
13- constructor ( message = 'Service temporarily unavailable due to open circuit breaker' ) {
13+ public statusCode : number = 503 ;
14+ constructor ( message : string = 'Service unavailable: Circuit breaker is OPEN' ) {
1415 super ( message ) ;
1516 this . name = 'CircuitBreakerOpenError' ;
1617 }
@@ -23,19 +24,21 @@ export class CircuitBreakerOpenError extends Error {
2324
2425export class CircuitBreaker {
2526 private state : CircuitState = CircuitState . CLOSED ;
26- private failureCount = 0 ;
27- private readonly failureThreshold : number ;
28- private readonly resetTimeoutMs : number ;
27+ private failureCount : number = 0 ;
2928 private lastStateChange : number = Date . now ( ) ;
29+ private readonly failureThreshold : number ;
30+ private readonly cooldownPeriodMs : number ;
3031
3132 constructor ( options : CircuitBreakerOptions = { } ) {
3233 this . failureThreshold = options . failureThreshold ?? 5 ;
33- this . resetTimeoutMs = options . resetTimeoutMs ?? 10000 ;
34+ this . cooldownPeriodMs = options . cooldownPeriodMs ?? 30000 ; // Default 30 seconds
3435 }
3536
3637 public getState ( ) : CircuitState {
37- if ( this . state === CircuitState . OPEN && Date . now ( ) - this . lastStateChange >= this . resetTimeoutMs ) {
38- this . state = CircuitState . HALF_OPEN ;
38+ if ( this . state === CircuitState . OPEN ) {
39+ if ( Date . now ( ) - this . lastStateChange >= this . cooldownPeriodMs ) {
40+ this . state = CircuitState . HALF_OPEN ;
41+ }
3942 }
4043 return this . state ;
4144 }
@@ -60,7 +63,6 @@ export class CircuitBreaker {
6063 private onSuccess ( ) : void {
6164 this . failureCount = 0 ;
6265 this . state = CircuitState . CLOSED ;
63- this . lastStateChange = Date . now ( ) ;
6466 }
6567
6668 private onFailure ( ) : void {
@@ -74,6 +76,11 @@ export class CircuitBreaker {
7476 public reset ( ) : void {
7577 this . state = CircuitState . CLOSED ;
7678 this . failureCount = 0 ;
77- this . lastStateChange = Date . now ( ) ;
7879 }
7980}
81+
82+ // Global/Per-endpoint instances
83+ export const fingerprintCircuitBreaker = new CircuitBreaker ( {
84+ failureThreshold : 3 ,
85+ cooldownPeriodMs : 15000 ,
86+ } ) ;
0 commit comments