Circuit Breaker

The :circuit_breaker plugin ensures that, for a given peer, once the error rate threshold is met, a “fail fast” mode is set by having httpx return the last known error for a grace period, after which the session tries to recover connectivity with peer, and “reopens” the circuit if successful.

It’s an implementation of the circuit breaker pattern.

http = HTTPX.plugin(:circuit_breaker)
http.get("http://www.qwwqjqwdjqiwdj.com")
#=> tries to resolve domain, #<HTTPX::ErrorResponse:0x000055a356257638 @error=#<HTTPX::NativeResolveError: Can't resolve www.qwwqjqwdjqiwdj.com>, ...
# repeat this often enough
http.get("http://www.qwwqjqwdjqiwdj.com")
#=> does not resolve domain, #<HTTPX::ErrorResponse:0x000055a356257638 , exact same object as the last call to the URL.
# wait a while
http.get("http://www.qwwqjqwdjqiwdj.com")
#=> may try the request again for real. #<HTTPX::ErrorResponse:0x000055a356257638

:circuit_breaker_max_attempts

(3 by default).

Used to set the maximum number of real requests attempted and failed, before the circuit is open.

:circuit_breaker_reset_attempts_in

(60 by default)

Used to set the period (in seconds) counting from the first failed attempt, during which failed attempts must happen which will open the circuit (if the max attempts isn’t reached within the interval, the number of attempts is reset).

:circuit_breaker_break_in

(60 by default)

Used to set the period (in seconds), for which an opened circuit will return the last failed attempt, after which the circuit will transition to the “half-open” state.

:circuit_breaker_half_open_drip_rate

(1.0 by default)

Fraction of requests which an “half-open” circuit will allow for real requests.

:circuit_breaker_break_on

(null by default, must be a proc yielding a response, and return truthy/falsy).

By default, the :circuit_breaker plugin only reacts on error responses (timeouts, connection issues, dns…), but leaves things such as HTTP error codes out. If you’d like to undo this, you can use this option to short-circuit, for instance, when 500 errors happen:

break_on = ->(response) { response.status == 500 }
http = HTTPX.plugin(:circuit_breaker, circuit_breaker_break_on: break_on)

Next: WebDav