Implement a Circuit Breaker
Problem Statement
Implement `createCircuitBreaker(fn, options)` to prevent cascading failures in distributed systems. States: - `'CLOSED'`: Normal operation. Calls `fn(...args)`. If consecutive failures reach `failureThreshold`, transition to `'OPEN'`. - `'OPEN'`: All calls immediately fail-fast (rejecting with Error('Circuit breaker is OPEN')) or call `fallback(...args)` if provided. After `resetTimeoutMs`, transition to `'HALF_OPEN'`. - `'HALF_OPEN'`: Allows a single trial request. If it succeeds, reset to `'CLOSED'`. If it fails, trip back to `'OPEN'` and reset the timer. Options: - `failureThreshold`: Number of consecutive failures before opening (default: 3). - `resetTimeoutMs`: Milliseconds to wait before half-opening (default: 1000). - `fallback`: Optional fallback function `(...args) => any` invoked when circuit is open. The returned wrapper function must also provide: - `getState()`: Returns `'CLOSED'`, `'OPEN'`, or `'HALF_OPEN'`. - `reset()`: Manually forces state back to `'CLOSED'`.
Examples
Example:
const breaker = createCircuitBreaker(fetchData, { failureThreshold: 2, resetTimeoutMs: 1000 });
await breaker(); // success (state: CLOSED)
// If next 2 calls fail -> state becomes OPEN
// Subsequent calls reject fast with Error('Circuit breaker is OPEN') without calling fetchDataPractice solo
3 test cases. No second person needed.