Packages

trait CircuitBreaker[-E] extends AnyRef

CircuitBreaker protects external resources against overload under failure

Operates in three states:

  • Closed (initial state / normal operation): calls are let through normally. Call failures and successes update the call statistics, eg failure count. When the statistics satisfy some criteria, the circuit breaker is 'tripped' and set to the Open state. Note that after this switch, in-flight calls are not canceled. Their success or failure does not affect the circuit breaker anymore though.
  • Open: all calls fail fast with a CircuitBreakerOpen error. After the reset timeout, the states changes to HalfOpen
  • HalfOpen: the first call is let through. Meanwhile all other calls fail with a CircuitBreakerOpen error. If the first call succeeds, the state changes to Closed again (normal operation). If it fails, the state changes back to Open. The reset timeout is governed by a reset policy, which is typically an exponential backoff.

Two tripping strategies are implemented: 1) Failure counting. When the number of successive failures exceeds a threshold, the circuit breaker is tripped.

Note that the maximum number of failures before tripping the circuit breaker is not absolute under concurrent execution. I.e. if you make 20 calls to a failing system in parallel via a circuit breaker with max 10 failures, the calls will be running concurrently. The circuit breaker will trip after 10 calls, but the remaining 10 that are in-flight will continue to run and fail as well.

TODO what to do if you want this kind of behavior, or should we make it an option?

2) Failure rate. When the fraction of failed calls in some sample period exceeds a threshold (between 0 and 1), the circuit breaker is tripped. The decision to trip the Circuit Breaker is made after every call (including successful ones!)

CircuitBreaker can record the following metrics, if a non-empty set of MetricLabels is given:

  • rezilience_circuit_breaker_state: current state (0 = closed, 1 = half-open, 2 = open)
  • rezilience_circuit_breaker_state_changes: number of state changes
  • rezilience_circuit_breaker_calls_success: number of successful calls
  • rezilience_circuit_breaker_calls_failure: number of failed calls
  • rezilience_circuit_breaker_calls_rejected: number of calls rejected in the open state
Self Type
CircuitBreaker[E]
Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. CircuitBreaker
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Abstract Value Members

  1. abstract def apply[R, E1 <: E, A](f: ZIO[R, E1, A]): ZIO[R, CircuitBreakerCallError[E1], A]

    Execute a given effect with the circuit breaker

    Execute a given effect with the circuit breaker

    f

    Effect to execute

    returns

    A ZIO that either succeeds with the success of the given f or fails with either a CircuitBreakerOpen or a WrappedError of the error of the given f

  2. abstract def currentState: UIO[State]
  3. abstract val stateChanges: ZIO[Scope, Nothing, Dequeue[StateChange]]

    Stream of Circuit Breaker state changes

    Stream of Circuit Breaker state changes

    Is backed by a zio.Hub, so each use of the Dequeue will receive all state changes

  4. abstract def widen[E2](pf: PartialFunction[E2, E]): CircuitBreaker[E2]

    Transform this policy to apply to larger class of errors

    Transform this policy to apply to larger class of errors

    Only for errors where the partial function is defined will errors be considered as failures, otherwise the error is passed through to the caller

    pf

    Map an error of type E2 to an error of type E

    returns

    A new CircuitBreaker defined for failures of type E2

Concrete Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##: Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @native() @IntrinsicCandidate()
  6. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  7. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  8. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @native() @IntrinsicCandidate()
  9. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native() @IntrinsicCandidate()
  10. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  11. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  12. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @IntrinsicCandidate()
  13. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @IntrinsicCandidate()
  14. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  15. def toPolicy: Policy[E]
  16. def toString(): String
    Definition Classes
    AnyRef → Any
  17. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  18. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()
  19. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])

Deprecated Value Members

  1. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable]) @Deprecated @Deprecated
    Deprecated

Inherited from AnyRef

Inherited from Any

Ungrouped