227. Design Rate Limit Circuit Breaker
Asked in
Design Rate Limit Circuit Breaker
Design a circuit breaker that protects a service when too many requests arrive in a short time. This circuit breaker opens based on the number of requests, not the number of failed requests.
The breaker has three states: CLOSED, OPEN, and HALF_OPEN. Requests are accepted only when the current state allows them.

Method Signatures

Constructor

CircuitBreaker(int requestLimit, int windowSeconds, int openSeconds)
  • Initializes the circuit breaker in CLOSED state.
  • requestLimit is the maximum number of accepted requests allowed inside one sliding time window.
  • windowSeconds is the sliding window size in seconds.
  • openSeconds is the number of seconds the breaker stays OPEN before becoming HALF_OPEN.

Handle Request

String handleRequest(int timestampSeconds)
  • Processes one incoming request at timestampSeconds.
  • Returns "ALLOWED,state" if the request is accepted.
  • Returns "REJECTED,state" if the request is rejected.
  • The returned state is the effective state before processing the request.

Get State

String getState(int timestampSeconds)
  • Returns the current effective state at timestampSeconds.
  • This method does not record a request.

State Rules

CLOSED

  • Only accepted requests are counted.
  • At timestamp t, the active sliding window contains accepted request timestamps x such that t - windowSeconds < x ≤ t.
  • For each request, remove accepted request timestamps outside the active sliding window.
  • If fewer than requestLimit accepted requests remain in the window, accept the new request and keep the breaker CLOSED.
  • If accepting the new request would exceed requestLimit, reject it and move the breaker to OPEN.
  • Multiple accepted requests with the same timestamp are counted as separate accepted requests.
  • Rejected requests are not added to the sliding window.

OPEN

  • All requests are rejected while the breaker is OPEN.
  • After openSeconds seconds have passed since the breaker opened, the effective state becomes HALF_OPEN.

HALF_OPEN

  • The first request in HALF_OPEN is accepted as a probe request.
  • After accepting this probe request, the breaker moves to CLOSED and starts a new request window containing only this probe request.

Deterministic Behavior

  • Requests are processed in the order method calls are received.
  • If multiple calls have the same timestamp, their call order decides the result.
  • The output must always be deterministic.
  • Before processing any public method call, the breaker first computes the effective state for the given timestamp.

Constraints

  • 1 ≤ requestLimit ≤ 1,000,000
  • 1 ≤ windowSeconds ≤ 1,000,000,000
  • 1 ≤ openSeconds ≤ 1,000,000,000
  • 0 ≤ timestampSeconds ≤ 1,000,000,000
  • Calls to handleRequest and getState use non-decreasing timestamps.
  • No parameter value will be null.

Examples

Example 1

CircuitBreaker(requestLimit = 3, windowSeconds = 10, openSeconds = 5)
handleRequest(timestampSeconds = 1) returns "ALLOWED,CLOSED"
handleRequest(timestampSeconds = 2) returns "ALLOWED,CLOSED"
handleRequest(timestampSeconds = 4) returns "ALLOWED,CLOSED"
handleRequest(timestampSeconds = 5) returns "REJECTED,CLOSED"
getState(timestampSeconds = 7) returns "OPEN"
getState(timestampSeconds = 10) returns "HALF_OPEN"
handleRequest(timestampSeconds = 10) returns "ALLOWED,HALF_OPEN"
getState(timestampSeconds = 10) returns "CLOSED"
The fourth request at time 5 is checked while the effective state is CLOSED. It would exceed the request limit inside the sliding window, so it is rejected and the breaker opens. At time 10, the open duration has passed, so the effective state is HALF_OPEN and one probe request is allowed.

Example 2

CircuitBreaker(requestLimit = 2, windowSeconds = 5, openSeconds = 3)
handleRequest(timestampSeconds = 1) returns "ALLOWED,CLOSED"
handleRequest(timestampSeconds = 3) returns "ALLOWED,CLOSED"
handleRequest(timestampSeconds = 6) returns "ALLOWED,CLOSED"
handleRequest(timestampSeconds = 7) returns "REJECTED,CLOSED"
At time 6, the active sliding window is (1, 6], so the request at time 1 is outside the active window. Therefore, the request at time 6 is accepted. At time 7, the active sliding window contains the accepted requests at times 3 and 6. Accepting another request would exceed the limit, so the request is rejected and the breaker opens.

Example 3

CircuitBreaker(requestLimit = 2, windowSeconds = 10, openSeconds = 4)
handleRequest(timestampSeconds = 100) returns "ALLOWED,CLOSED"
handleRequest(timestampSeconds = 100) returns "ALLOWED,CLOSED"
handleRequest(timestampSeconds = 100) returns "REJECTED,CLOSED"
Calls with the same timestamp are processed in method call order. The third request is checked while the effective state is CLOSED, but accepting it would exceed the limit, so it is rejected and the breaker opens.


Please use Laptop/Desktop or any other large screen to add/edit code.