Circuit::Breaker is a Crystal implementation of the Circuit Breaker pattern, which is useful for avoiding calling into code that is likely to fail.
For example:
- third-party API calls that occasionally result in HTTP failure responses, such as 429, 500, or 503
- slow database queries that timeout when the database is under load
If they begin failing, the circuit breaker can "open". Similar to how an open electrical circuit stops the flow of electricity, this doesn't actually invoke the code wrapped in the circuit breaker and instead it just fails immediately.
After some time has passed (customizable on the breaker itself), it will start trying to execute the block again — this is known as the "half-open" state. If it succeeds, the breaker will work normally again (that is, it returns to a "closed" state).
-
Add the dependency to your
shard.yml:dependencies: circuit: github: jgaskins/circuit
-
Run
shards install
require "circuit"Any time you're dealing with systems that have a meaningful likelihood of failing, such as third-party APIs or slow SQL queries that time out, you can wrap a Circuit::Breaker around it. Ideally you'd use the same instance for all related calls:
GitHubAPIBreaker = Circuit::Breaker.new(
name: "GitHub API",
failure_threshold: 10,
errors: [GitHub::Error],
)
GitHubAPIBreaker.call do
github
.repo(event.repository)
.issue(event.issue)
.comment(event.comment)
.reactions
.create(:eyes)
endSlowQueryBreaker = Circuit::Breaker.new(
name: "Slow SQL queries",
failure_threshold: 5,
)
SlowQueryBreaker.call do |tracker|
start = Time.instant
run_query
if start.elapsed > 1.second
tracker.fail
end
end- Fork it (https://github.com/jgaskins/circuit/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
This shard was extracted from Malakai to avoid calling third-party APIs.
- Jamie Gaskins - creator and maintainer