AniUI Academy

Build a circuit breaker

hardAsync & Promises+350 XPPractice

Hammering a service that is already failing makes the outage worse and makes your UI slow, since every call waits for a timeout. A circuit breaker trips after a run of failures and fails fast instead, then lets a single trial call through later to see if the service is back.

Implement createBreaker(task, options) where options may contain failureThreshold (default 3) and resetTimeout (default 1000). It returns a function call(...args) that forwards its arguments to task, plus a call.state() method returning "closed", "open" or "half-open". It starts closed. A fulfilment resets the consecutive-failure count to zero. Once failureThreshold consecutive failures happen, the breaker opens and records the time: while open, call rejects with new Error("Circuit is open") without invoking task. Once resetTimeout milliseconds have passed since it opened, state() reports "half-open" and the next call does invoke task: if it fulfils the breaker closes and the count resets, and if it rejects the breaker opens again with a fresh timestamp.

Arguments

task(...args: any[]) => Promise<T>
The underlying function to guard.
options{ failureThreshold?: number, resetTimeout?: number }
failureThreshold defaults to 3, resetTimeout to 1000ms.

Returns

Function — A call(...args) function that forwards to task. Also exposes call.state() returning "closed", "open", or "half-open".

Examples

const call = createBreaker(fetchJson, {
  failureThreshold: 5,
  resetTimeout: 10000,
});

// After 5 consecutive failures the breaker opens, and the next call rejects
// immediately with Error("Circuit is open") without touching the network —
// until 10 seconds pass, when a single trial call is let through.

Fail fast when the downstream is already dead.

What it has to do

  • Forward arguments to task and resolve with its value while closed.
  • Open after failureThreshold consecutive failures.
  • Reject with an Error reading Circuit is open without calling task while open.
  • Reset the failure count on any success.
  • Report half-open after resetTimeout, and close again on a successful trial call.

Notes

  • Derive the half-open state from the clock rather than storing it — the breaker is half-open any time Date.now() - openedAt >= resetTimeout.
  • A success in the half-open trial fully closes the breaker and resets the count; a failure re-opens with a fresh timestamp.

Stuck? The javascript course covers everything this challenge needs.

Try it yourself
Loading playground...
5 tests · +350 XP

Discussion

Sign in to post
Sign in to join the conversation.Sign in

No comments yet. Be the first to say something.