Circuit Breaker in Akka

Reading Time: 3 minutes

Hey everyone, in today’s blog I will be covering the concept of Circuit Breaker in Akka. Before moving forward to it just think of a situation when you are requesting on a website and it is taking too much time. You try to refresh the page and still the same. Would you like to use that website again? I think the answer will be no. Now if you are a developer what will you do? There could be many ways for solving this situation and the circuit breaker can be a help here.

What is a Circuit Breaker?

Accept it that failures are everywhere and even with every software. Especially when there are remote calls then the probability of failure is more. Now if there are many users and your server/supplier is unresponsive, you will soon run out of critical resources. And all this can lead to cascading failures across multiple systems.

Circuit Breaker pattern can be used to prevent this. In this, you wrap a protected function call in a Circuit Breaker object which monitors the failures.  Once the failures reach a certain threshold, the circuit breaker trips, and all further calls to the circuit breaker return with an error, without the protected call being made at all.

The Circuit breaker pattern helps to prevent catastrophic cascading failure across multiple systems.

Circuit Breaker in Akka

Now we have an idea about circuit breaker. In this part we will have a look at what circuit breaker do and how it is implemented in Akka.

Different States of a Circuit Breaker

Circuit Breaker has 3 states in which it operates. Following is their description:

  • Open: After tolerating a defined number of failures the circuit comes in the open state. In this, all the calls fail-fast, producing a CircuitBreakerOpenException. After the reset timeout, it enters in the half-open state.
  • Half-Open: In the half-open state, the first call attempted is allowed without failing fast. Now there are 2 possibilities, it can succeed or fail again. If it fails again then it goes in the open state and if the call succeeds then the circuit breaker goes in the close state after resetting the circuit breaker.
  • Close: When the calls are working normally then it is in close state. In this exceptions or calls exceeding the configured call timeout increment a failure counter and every success call reset the failure count. When the failure counter reaches a max failure count then the circuit goes in the open state.

There are callbacks for every state i.e. onOpen, onClose and onHalfOpen.

Implementation in Akka

Akka provides us with the circuit breaker functionality that can be used for providing stability when working with dangerous operations through Circuit Breaker class.

Creating an instance

For creating an instance, you will have to provide the following:

  • scheduler: an Akka scheduler
  • maxFailures: maximum number of failures that it will tolerate before opening a circuit
  • callTimeout: this is the time after which a call is considered to be failed
  • resetTimeout: this is the time after which there will be an attempt for closing the circuit

And with above we can provide callbacks too.

val breaker =
    new CircuitBreaker(system.scheduler,
      maxFailures = 10,
      callTimeout = 1 seconds,
      resetTimeout = 1 seconds).
      onOpen(println("circuit breaker opened!")).
      onClose(println("circuit breaker closed!")).
      onHalfOpen(println("circuit breaker half-open"))

The purpose of the circuit breaker is to protect your system from cascading failures with synchronous as well as asynchronous calls. 

Wrapping Asynchronous Calls

For handling asynchronous calls, we use withCircuitBreaker that accepts a Future.

 val askFuture = breaker.withCircuitBreaker(db ? GetRequest("key"))

Wrapping synchronous calls

For handling synchronous calls, we use withSyncCircuitBreaker that accepts a body.

breaker.withSyncCircuitBreaker(8888)

Increasing Failure Count Explicitly

A circuit breaker treats an exception as a failure and increases the failure count on each of them. But there could be a use case when you want to increase the count even when the call succeeds. This can be done by providing “defineFailureFn”.

 val evenNumberAsFailure: Try[Int] => Boolean = {
      case Success(n) => n % 2 == 0
      case Failure(_) => true

    }
      breaker.withSyncCircuitBreaker(
      8888
,
      evenNumberAsFailure)

This was a short introduction to the Circuit Breakers in Akka. I hope it was helpful. 😁

References