This is a light weigth implementation of the Circuit Breaker design pattern done in Swift. A circuit breaker is useful for when performing some kind of work that could fail and wanting to repeat the work based on a given configuration or threshold. When the threshold is met, the circuit breaker will trip, preventing unnecessary load until the breaker resets after a timeout. This implementation provides an easy to use way of monitoring timeouts and supporting retry logic.
Platforms
iOS: 9.0 and greater
macOS: 10.9 and greater
Linux
Install
CocoaPods
You can use CocoaPods to install SGCircuitBreaker by adding it to your Podfile:
platform :ios, '9.0'
use_frameworks
target 'MyApp' do
pod 'SGCircuitBreaker'
end
Carthage
You can use Carthage to install SGCircuitBreaker by adding it to your Cartfile:
github "eman6576/SGCircuitBreaker"
Swift Package Manager
You can use Swift Package Manager to install SGCircuitBreaker by adding the proper description to your Package.swift file:
Here we register the work that needs to be performed. The work is calling an asynchronous method on mockService that could fail. In the closure for the method call, we check if an error occured. If it did, we report to the circuit breaker that the work failed by calling circuitBreaker.failure(error: error) and pass the error. This will check if the maximum amount of failures have been met or not. If the maximum amount hasn’t been met, then the circuit breaker would wait for a certain amount of time before trying the work again. The circuit breaker would be in the halfOpened state. If the maximum amount of failures are met, then the circuit breaker trips. If an error didn’t occur, then we report to the circuit breaker that the work was successful by calling circuitBreaker.success(). This will reset the circuit breaker to its initial state of closed.
Now what happens if the circuit breaker trips. We want to be able to handle this and perform any error handling logic neccessary that will not break our application. We can register how to handle the circuit breaker tripping like so:
circuitBreaker.tripped = { (circuitBreaker, error) in
print("Error occured with breaker: \(error)")
}
Here we register a handler for when the circuit breaker trips. An Error? is passed that represents the last error that was reported. At this point, the circuit breaker is in the open state.
There might be some cases where you need to know if the circuit breaker was successful. This also means when a success is reported to the circuit breaker. We can register a handler like so:
circuitBreaker.successful { (circuitBreaker) in
print("Circuit breaker was successful")
}
We can also handle when the circuit breaker reaches the set timeout. We can use it to cancel the registered work like so:
Once we have set up our handlers, we need to start the circuit breaker like so:
circuitBreaker.start()
Here is a full example of how the circuit breaker would be used:
let circuitBreaker = SGCircuitBreaker(
timeout: 20,
maxFailures: 4,
retyDelay: 3
)
circuitBreaker.workToPerform = { [weak self] (circuitBreaker) in
self?.mockService.call { (data, error) in
guard error == nil else {
circuitBreaker.failure(error: error)
return
}
circuitBreaker.success()
}
}
circuitBreaker.tripped = { (circuitBreaker, error) in
print("Error occured with breaker: \(error)")
}
circuitBreaker.successful { (circuitBreaker) in
print("Circuit breaker was successful")
}
circuitBreaker.timedOut = { [weak self] (circuitBreaker) in
print("Timeout reached")
self?.mockService.cancel()
}
circuitBreaker.start()
Initial Configuration
SGCircuitBreaker can be configured with three parameters:
timeout: A TimeInterval representing how long the registered work has to finish before throwing an error. Defaults to 10.
maxFailures: An Int representing the number of failures allowed for retrying to performing the registered work before tripping. Defaults to 3.
retryDelay: A TimeInterval representing how long to wait before retrying the registered work after a failure. Defailts to 2.
Public Interface
SGCircuitBreaker contains some public methods and attributes:
Methods
start(): Starts the circuit breaker.
success(): Reports to the circuit breaker that the registered work was successful.
failure(error: Error? = nil): Reports to the circuit breaker that the registered work failed.
reset(): Resets the circuit breaker.
Attributes
failureCount: Current number of failures.
state: The current state of the circuit breaker. Can be either open, halfOpened, or closed.
Logging
SGCircuitBreaker can log to the console different events that occur within the circuit breaker. By default, this is not enabled. If you would like to enable it you can enable it when creating an instance like so:
let circuitBreaker = SGCircuitBreaker(loggingEnabled: true)
You can also change this property at anytime as well:
circuitBreaker.loggingEnabled = true
When an event is logged, this is what it would look like in the console:
SGCircuitBreaker: Registered work was successful. 🎉
A Swift implementation of the Circuit Breaker design pattern
Table of Contents
Background
This is a light weigth implementation of the Circuit Breaker design pattern done in Swift. A circuit breaker is useful for when performing some kind of work that could fail and wanting to repeat the work based on a given configuration or threshold. When the threshold is met, the circuit breaker will trip, preventing unnecessary load until the breaker resets after a timeout. This implementation provides an easy to use way of monitoring timeouts and supporting retry logic.
Platforms
Install
CocoaPods
You can use CocoaPods to install
SGCircuitBreaker
by adding it to yourPodfile
:Carthage
You can use Carthage to install
SGCircuitBreaker
by adding it to yourCartfile
:Swift Package Manager
You can use Swift Package Manager to install
SGCircuitBreaker
by adding the proper description to yourPackage.swift
file:Usage
Initialization
To access the available data types, import
SGCircuitBreaker
into your project like so:We can instantiate an instance of
SGCircuitBreaker
in one of two ways:using the default configuration or like
Functionality
With a circuit breaker instance, we need to register the work that needs to be performed:
Here we register the work that needs to be performed. The work is calling an asynchronous method on
mockService
that could fail. In the closure for the methodcall
, we check if an error occured. If it did, we report to the circuit breaker that the work failed by callingcircuitBreaker.failure(error: error)
and pass the error. This will check if the maximum amount of failures have been met or not. If the maximum amount hasn’t been met, then the circuit breaker would wait for a certain amount of time before trying the work again. The circuit breaker would be in thehalfOpened
state. If the maximum amount of failures are met, then the circuit breaker trips. If an error didn’t occur, then we report to the circuit breaker that the work was successful by callingcircuitBreaker.success()
. This will reset the circuit breaker to its initial state ofclosed
.Now what happens if the circuit breaker trips. We want to be able to handle this and perform any error handling logic neccessary that will not break our application. We can register how to handle the circuit breaker tripping like so:
Here we register a handler for when the circuit breaker trips. An
Error?
is passed that represents the last error that was reported. At this point, the circuit breaker is in theopen
state.There might be some cases where you need to know if the circuit breaker was successful. This also means when a success is reported to the circuit breaker. We can register a handler like so:
We can also handle when the circuit breaker reaches the set timeout. We can use it to cancel the registered work like so:
Once we have set up our handlers, we need to start the circuit breaker like so:
Here is a full example of how the circuit breaker would be used:
Initial Configuration
SGCircuitBreaker
can be configured with three parameters:timeout
: ATimeInterval
representing how long the registered work has to finish before throwing an error. Defaults to 10.maxFailures
: AnInt
representing the number of failures allowed for retrying to performing the registered work before tripping. Defaults to 3.retryDelay
: ATimeInterval
representing how long to wait before retrying the registered work after a failure. Defailts to 2.Public Interface
SGCircuitBreaker
contains some public methods and attributes:Methods
start()
: Starts the circuit breaker.success()
: Reports to the circuit breaker that the registered work was successful.failure(error: Error? = nil)
: Reports to the circuit breaker that the registered work failed.reset()
: Resets the circuit breaker.Attributes
failureCount
: Current number of failures.state
: The current state of the circuit breaker. Can be eitheropen
,halfOpened
, orclosed
.Logging
SGCircuitBreaker
can log to the console different events that occur within the circuit breaker. By default, this is not enabled. If you would like to enable it you can enable it when creating an instance like so:You can also change this property at anytime as well:
When an event is logged, this is what it would look like in the console:
Tests
See SGCircuitBreakerTests.swift for some examples on how to use it.
Contribute
See the contribute file!
PRs accepted.
Small note: If editing the Readme, please conform to the standard-readme specification.
Maintainers
Manny Guerrero

License
MIT © Manny Guerrero.