Announcing Stoplight, a Ruby circuit breaker gem
I am proud to announce the first stable release of Stoplight! It’s like traffic control for your code. Stoplight implements the circuit breaker design pattern in Ruby. Use it to gracefully handle things that occasionally fail.
To get started, install the
Once you’ve done that, use the
Stoplight method to create
stoplights. Each stoplight needs a name and a block to run. Here’s
a simple example that calculates a rough approximation of pi.
Stoplights start off green. If they fail enough, they switch to red. When they’re red, they short circuit and raise an error. Here’s an example that will never succeed.
By default, stoplights pass errors through them. When they’re red, they’ll raise a red light error. Sometimes it makes sense to return a default value instead. You can do this by using a fallback. If the stoplight is green and raises an error, it’ll run the fallback. If the stoplight is red, it’ll run the fallback instead of raising an error. Here’s an example that uses a fallback.
These examples scratch the surface of what stoplights can do. They are highly configurable. Check out the readme for more examples and settings.
Six months ago, OrgSync experienced a few hours of downtime. It started with a few external services taking longer than expected to respond. Those delays created a negative feedback loop that eventually brought the site down.
We decided to wrap those external services in circuit breakers to protect ourselves from these types of failures. We knew of a few circuit breaker gems and looked for more. We had a few requirements to meet:
State had to be persisted to an external data store like Redis. We run many Rails front ends that need to be synchronized.
The circuits had to return the result of running their block. We weren’t using these solely for their side effects.
Any other features, like logging or metrics, were actually antifeatures to us. We can handle those things our own way.
We evaluated all of the gems we could find, but ultimately none of them were right for us. So Cameron Desautels and I started developing Stoplight. Those other gems did inspire us, though. I’ll briefly cover them here. You might find one of them useful if Stoplight isn’t right for you.
Breaker was created by Adam Hawkins. It has a lot in common with Stoplight. It’s simple, has great documentation, and supports external data stores. Unfortunately there’s no interface for the data stores, so you have no choice but to read the reference implementation.
Aleksey Gureev created CircuitB. It also supports external data stores. Unfortunately it requires configuring circuits ahead of time. It also doesn’t return the result of the block (although that will be fixed in version 1.2). Those were deal breakers for us, so we couldn’t use it.
Will Sargent at Typesafe created CircuitBreaker. It actually implements a state machine behind the scenes. That makes it easy to debug, but hard to use with external data stores. It’s also intended to be used as a mixin, which isn’t what we had in mind.
Yann Armand at Yammer created Circuitbox. Of all the circuit breaker gems, it feels the most heavyweight. It depends on ActiveSupport, which provides external data stores and logging. It also supports advanced percentage-based heuristics.
Julius Volz and Tobias Schmidt at SoundCloud created SimpleCircuitBreaker. It definitely lives up to its name. At less than 60 lines of code, it’s the simplest circuit breaker gem available. This is probably how every other gem started out. Because of its simplicity, it doesn’t support external data stores.
Patrick Huesler at Wooga created YaCircuitBreaker. It’s
one of the few that allows you to manually manage the state with
#reset!. Unfortunately it has a few problems. It
doesn’t support external data stores, the gem name (
isn’t what you require (
circuit_breaker), and it doesn’t return
the result of the block.
[This post was originally posted to my blog.]
Taylor Fausak was born in California, but he got to Texas as soon as he could. He studied Computer Science at the University of Texas at Austin before entering the wild world of software development. After a brief stint at Cisco, he started his career at Famigo working on all aspects of web development. Then he swapped his Django experience for a chunky slice of Rails bacon and joined OrgSync in the fall of 2012. When he's not slinging code around, he likes riding bikes, playing Magic, and throwing frisbees.
comments powered by Disqus