Decorator that stops calling a function after it fails repeatedly, so callers fail fast instead of waiting on something that is down. It has three states:
Details
closed: calls go through. Consecutive errors are counted.
open: after
failuresconsecutive errors, calls fail immediately with agarnish_circuit_openerror, without running the function, forreset_afterseconds.half-open: once the cooldown has passed, the next call runs as a trial. If it succeeds the circuit closes. If it fails the circuit opens again for another cooldown.
Only errors count as failures. A call that returns normally, whatever its value, resets the count. Each decorated function keeps its own state.
Stack it outside retry() so an open circuit rejects a call before any
retries happen:
fetch := circuit_breaker(failures = 3, reset_after = 30) %@%
retry(stop = stop_after_attempt(3)) %@%
function(url) { ... }Examples
n <- 0
flaky <- function() {
n <<- n + 1
stop("service down")
}
f := circuit_breaker(failures = 2, reset_after = 60) %@% flaky
try(f())
#> Error in <environment>$fn() : service down
try(f())
#> Error in <environment>$fn() : service down
try(f()) # rejected without calling flaky()
#> Error : Circuit is open: the function failed repeatedly and is not being called.
n # still 2
#> [1] 2