“A whimsical illustration showcasing a red toy train labeled ‘BB8’ and ‘20’ chugging along tracks, passing near a large, white, 3D Ruby programming language logo, which looks like a gem. Both the train and the Ruby gem are connected through vibrant red wiring to a central yellow switch box. The entire scene is set against a soft teal background, punctuated by tiny yellow stars, giving a magical ambiance.
Chugging along the Rails: Where the magic of toy trains meets the power of Ruby.

Implementing a Circuit Breaker in Rails

Alessio Bussolari
2 min readOct 17, 2023

--

The Circuit Breaker pattern is a design pattern used in software development to improve the stability and resilience of a system. In a Rails application, using a circuit breaker can prevent your system from making unnecessary requests to external services when they are known to be failing. This pattern can be particularly useful when your Rails application interacts with external APIs, databases, or other microservices.

The Basics of the Circuit Breaker Pattern

Think of a circuit breaker in electrical systems. It trips or “breaks” the circuit when there’s too much current, preventing potential damage. Similarly, in software, a circuit breaker “trips” when certain conditions are met, usually after detecting that a particular service is unavailable or failing.

Here are the three primary states of a circuit breaker:

  1. Closed: Everything is functioning as expected. Requests are made to the external service.
  2. Open: The external service is down or unresponsive. Requests are not made; instead, failures are returned immediately.
  3. Half-Open: After a predetermined amount of time, the circuit breaker allows some requests to check if the service has recovered. If it’s stable, the state returns to Closed; otherwise, it remains Open.

Implementing a Simple Circuit Breaker in Rails

Let’s design a simple circuit breaker without relying on any gems or plugins.

Model the Circuit Breaker

class CircuitBreaker
attr_accessor :failure_count, :state, :last_failed_time

FAILURE_THRESHOLD = 5
HALF_OPEN_TIME = 60 # seconds

def initialize
@failure_count = 0
@state = :closed
@last_failed_time = nil
end

def request
case state
when :closed
make_request
when :open
raise "Service Unavailable"
when :half_open
make_request if Time.now - last_failed_time >= HALF_OPEN_TIME
end
end

private

def make_request
# Replace with your actual request to an external service
response = ExternalService.call

if response.success?
reset
else
register_failure
end
rescue
register_failure
raise "Service Error"
end…

--

--

Alessio Bussolari

Ruby on Rails programmer since 2009. Current CTO at COSMIC SRL, where I lead the team in creating innovative solutions.