Circuit Breaker Pattern
In the real world, circuit breakers are used to prevent electrical faults. To prevent bigger problems, the circuit breaker is automatically activated in case of a problem.
Developers like to adapt real world solutions to software. In this article, we will talk about circuit breakers for software.
The Theory
Many applications need to communicate with different sources. Sometimes we may need to connect the DB or cache driver, sometimes we use synchronous remote calls. Each factor affects the app’s health. Because, sometimes we may not be able to communicate with them for any reason.
It will be a waste of both resources and time to perform a transaction knowing that we will get a failure. Also, the rollback scenario may be hard on large systems. Instead of this if we know the transaction may be a failure, we can prevent it instead of execute.
That’s exactly the mission of the circuit breaker.
Important Variables
To implement a circuit breaker, it is useful to know some keywords for your workflow. We need to keep some data to determine state.
Threshold
It keeps the maximum number of failures allowed. If the number of failures exceeds this value, the circuit breaker will be open.
Timeout
When the Circuit Breaker is in the open state, it must allow limited transactions after waiting for a while. Because we need to repair the state. Here it is defined how long to wait after the last failed transaction.
Failure Transactions
We need to keep count of failure and last failure timestamp. This data may be kept in Redis, DB or etc for not losing these values. However, these values may be array. Sometimes, you need to separate failures status.
For example, the exchange service requests should be executed even if the weather service is blocked.
States
Generally, the Circuit Breaker pattern has 3 states. We don’t have best practices for changing the state. Depending on the application needs the state changer strategies may be different.
Closed
The default state is closed. This means the count of failures did not exceed the threshold and the system is working as expected. In this state all transactions will be processed without preventing.
Open
When the number of failures exceeds the threshold, the circuit breaker will change state to open. The transactions are blocked immediately without being attempted.
In this state your application can have a different strategy. For example, you can return cached data when the API requests are blocked.
Half-Open
In this state, the circuit breaker allows some transactions. The state may be closed when the transactions are successful. But, if the transactions continue to fail the state will be open.
Your application may follow different strategies when returning open or closed state.
For example, sometimes you can reset the previous failures when a transaction executed successfully or you can stay half-open state for some failures. In this case no best practices. Because each application’s requirements are different.
TL;DR
The Circuit Breaker pattern prevents the execution of a potentially failing operation.
Example
Now we will prepare a very simple class of circuit breaker. Normally circuit breaker states need to be kept as permanently. We keep it in the Redis.
For simplicity in this example, we will keep it simple with class property.
This is a very simple class. The circuit breaker will be open when 20 transactions have failed. Operations are inhibited when the circuit breaker is in open mode. However, some transactions are retried 30 seconds after the last failure. And the new status is determined according to the transaction’s status.
Example usage:
Output:
string(25) "the default state: closed"
string(23) "after 20 failures: open"
string(24) "after wait 10 secs: open"
string(29) "after wait 30 secs: half-open"
string(26) "after successfully: closed"
string(25) "after again failure: open"
References
For more about this pattern:
- Circuit Breaker by Martin Fowlers
- Circuit Breaker design pattern on Wikipedia