-
-
Save halorgium/0e12f28337f80cb959e4 to your computer and use it in GitHub Desktop.
circuit breaker in Celluloid
depends on https://github.com/wsargent/circuit_breaker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'celluloid' | |
require 'celluloid/proxies/circuit_breaker' | |
def safely | |
p yield | |
rescue StandardError | |
p $! | |
end | |
class Foo | |
include Celluloid | |
def win | |
1 | |
end | |
def slow | |
sleep 4 | |
2 | |
end | |
def lose | |
abort "lose" | |
end | |
end | |
foo = Foo.new | |
class Handler | |
end | |
breaker = Celluloid::CircuitBreaker.new(foo) do |config| | |
config.invocation_timeout = 3 | |
end | |
safely { breaker.win } | |
safely { breaker.win } | |
safely { breaker.win } | |
10.times do | |
safely { breaker.lose } | |
end | |
10.times do | |
safely { breaker.win } | |
sleep 1 | |
end | |
safely { breaker.slow } | |
safely { breaker.win } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'circuit_breaker' # from https://github.com/wsargent/circuit_breaker | |
module Celluloid | |
class CircuitBreaker < AbstractProxy | |
class Handler < ::CircuitBreaker::CircuitHandler | |
def initialize(proxy, logger = nil) | |
super(logger) | |
@proxy = proxy | |
end | |
def handle(circuit_state, meth, *args, &block) | |
if is_tripped(circuit_state) | |
@logger.debug("handle: breaker is tripped, refusing to execute: #{circuit_state.inspect}") if @logger | |
on_circuit_open(circuit_state) | |
end | |
begin | |
out = nil | |
future = @proxy.future meth, *args, &block | |
out = future.value(@invocation_timeout) | |
on_success(circuit_state) | |
rescue Exception | |
on_failure(circuit_state) | |
raise | |
end | |
return out | |
end | |
end | |
def initialize(proxy) | |
@proxy = proxy | |
@klass = proxy.class.to_s | |
@handler = Handler.new(@proxy, ::Celluloid::Logger) | |
yield @handler if block_given? | |
@state = @handler.new_circuit_state | |
end | |
def inspect | |
"#<Celluloid::CircuitBreaker(#{@klass})>" | |
end | |
def method_missing(meth, *args, &block) | |
@handler.handle(@state, meth, *args, &block) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
D, [2013-03-29T01:15:30.361250 #26911] DEBUG -- : on_success: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=nil, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:30.361391 #26911] DEBUG -- : on_success: reset_failure_count #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=nil, @aasm_current_state=:closed> | |
1 | |
D, [2013-03-29T01:15:30.361794 #26911] DEBUG -- : on_success: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=nil, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:30.361853 #26911] DEBUG -- : on_success: reset_failure_count #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=nil, @aasm_current_state=:closed> | |
1 | |
D, [2013-03-29T01:15:30.362234 #26911] DEBUG -- : on_success: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=nil, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:30.362340 #26911] DEBUG -- : on_success: reset_failure_count #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=nil, @aasm_current_state=:closed> | |
1 | |
D, [2013-03-29T01:15:30.362823 #26911] DEBUG -- : on_failure: circuit_state = #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=nil, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:30.362879 #26911] DEBUG -- : is_failure_threshold_reached: 1 > 5 == false | |
#<RuntimeError: lose> | |
D, [2013-03-29T01:15:30.363390 #26911] DEBUG -- : on_failure: circuit_state = #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=1, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:30.363463 #26911] DEBUG -- : is_failure_threshold_reached: 2 > 5 == false | |
#<RuntimeError: lose> | |
D, [2013-03-29T01:15:30.363931 #26911] DEBUG -- : on_failure: circuit_state = #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=2, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:30.363982 #26911] DEBUG -- : is_failure_threshold_reached: 3 > 5 == false | |
#<RuntimeError: lose> | |
D, [2013-03-29T01:15:30.364424 #26911] DEBUG -- : on_failure: circuit_state = #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=3, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:30.364473 #26911] DEBUG -- : is_failure_threshold_reached: 4 > 5 == false | |
#<RuntimeError: lose> | |
D, [2013-03-29T01:15:30.364939 #26911] DEBUG -- : on_failure: circuit_state = #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=4, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:30.364989 #26911] DEBUG -- : is_failure_threshold_reached: 5 > 5 == false | |
#<RuntimeError: lose> | |
D, [2013-03-29T01:15:30.365429 #26911] DEBUG -- : on_failure: circuit_state = #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=5, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:30.365479 #26911] DEBUG -- : is_failure_threshold_reached: 6 > 5 == true | |
D, [2013-03-29T01:15:30.365535 #26911] DEBUG -- : on_failure: tripping circuit breaker #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
#<RuntimeError: lose> | |
D, [2013-03-29T01:15:30.365801 #26911] DEBUG -- : timeout_exceeded: time since last failure = 0.000301 | |
D, [2013-03-29T01:15:30.365863 #26911] DEBUG -- : handle: breaker is tripped, refusing to execute: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:30.365918 #26911] DEBUG -- : on_circuit_open: raising for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
#<CircuitBreaker::CircuitBrokenException: Circuit broken, please wait for timeout> | |
D, [2013-03-29T01:15:30.365997 #26911] DEBUG -- : timeout_exceeded: time since last failure = 0.000514 | |
D, [2013-03-29T01:15:30.366054 #26911] DEBUG -- : handle: breaker is tripped, refusing to execute: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:30.366107 #26911] DEBUG -- : on_circuit_open: raising for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
#<CircuitBreaker::CircuitBrokenException: Circuit broken, please wait for timeout> | |
D, [2013-03-29T01:15:30.366178 #26911] DEBUG -- : timeout_exceeded: time since last failure = 0.000695 | |
D, [2013-03-29T01:15:30.366234 #26911] DEBUG -- : handle: breaker is tripped, refusing to execute: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:30.366287 #26911] DEBUG -- : on_circuit_open: raising for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
#<CircuitBreaker::CircuitBrokenException: Circuit broken, please wait for timeout> | |
D, [2013-03-29T01:15:30.366355 #26911] DEBUG -- : timeout_exceeded: time since last failure = 0.000873 | |
D, [2013-03-29T01:15:30.366411 #26911] DEBUG -- : handle: breaker is tripped, refusing to execute: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:30.366464 #26911] DEBUG -- : on_circuit_open: raising for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
#<CircuitBreaker::CircuitBrokenException: Circuit broken, please wait for timeout> | |
D, [2013-03-29T01:15:30.366535 #26911] DEBUG -- : timeout_exceeded: time since last failure = 0.001053 | |
D, [2013-03-29T01:15:30.366591 #26911] DEBUG -- : handle: breaker is tripped, refusing to execute: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:30.366644 #26911] DEBUG -- : on_circuit_open: raising for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
#<CircuitBreaker::CircuitBrokenException: Circuit broken, please wait for timeout> | |
D, [2013-03-29T01:15:31.368075 #26911] DEBUG -- : timeout_exceeded: time since last failure = 1.002402 | |
D, [2013-03-29T01:15:31.368634 #26911] DEBUG -- : handle: breaker is tripped, refusing to execute: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:31.369249 #26911] DEBUG -- : on_circuit_open: raising for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
#<CircuitBreaker::CircuitBrokenException: Circuit broken, please wait for timeout> | |
D, [2013-03-29T01:15:32.370125 #26911] DEBUG -- : timeout_exceeded: time since last failure = 2.004575 | |
D, [2013-03-29T01:15:32.370441 #26911] DEBUG -- : handle: breaker is tripped, refusing to execute: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:32.370726 #26911] DEBUG -- : on_circuit_open: raising for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
#<CircuitBreaker::CircuitBrokenException: Circuit broken, please wait for timeout> | |
D, [2013-03-29T01:15:33.371245 #26911] DEBUG -- : timeout_exceeded: time since last failure = 3.005714 | |
D, [2013-03-29T01:15:33.371443 #26911] DEBUG -- : handle: breaker is tripped, refusing to execute: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:33.371541 #26911] DEBUG -- : on_circuit_open: raising for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
#<CircuitBreaker::CircuitBrokenException: Circuit broken, please wait for timeout> | |
D, [2013-03-29T01:15:34.372426 #26911] DEBUG -- : timeout_exceeded: time since last failure = 4.00681 | |
D, [2013-03-29T01:15:34.372739 #26911] DEBUG -- : handle: breaker is tripped, refusing to execute: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:34.373151 #26911] DEBUG -- : on_circuit_open: raising for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
#<CircuitBreaker::CircuitBrokenException: Circuit broken, please wait for timeout> | |
D, [2013-03-29T01:15:35.374694 #26911] DEBUG -- : timeout_exceeded: time since last failure = 5.009155 | |
D, [2013-03-29T01:15:35.374953 #26911] DEBUG -- : is_tripped: attempting reset into half open state for #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:open> | |
D, [2013-03-29T01:15:35.376045 #26911] DEBUG -- : on_success: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:half_open> | |
D, [2013-03-29T01:15:35.376133 #26911] DEBUG -- : on_success: reset circuit #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=6, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:half_open> | |
1 | |
D, [2013-03-29T01:15:36.378121 #26911] DEBUG -- : on_success: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:36.378221 #26911] DEBUG -- : on_success: reset_failure_count #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
1 | |
D, [2013-03-29T01:15:37.380429 #26911] DEBUG -- : on_success: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:37.380587 #26911] DEBUG -- : on_success: reset_failure_count #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
1 | |
D, [2013-03-29T01:15:38.383204 #26911] DEBUG -- : on_success: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:38.383497 #26911] DEBUG -- : on_success: reset_failure_count #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
1 | |
D, [2013-03-29T01:15:39.386136 #26911] DEBUG -- : on_success: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:39.386326 #26911] DEBUG -- : on_success: reset_failure_count #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
1 | |
D, [2013-03-29T01:15:43.389012 #26911] DEBUG -- : on_failure: circuit_state = #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=0, @last_failure_time=2013-03-29 01:15:30 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:43.389244 #26911] DEBUG -- : is_failure_threshold_reached: 1 > 5 == false | |
#<Celluloid::TimeoutError: Timed out> | |
D, [2013-03-29T01:15:43.390800 #26911] DEBUG -- : on_success: #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=1, @last_failure_time=2013-03-29 01:15:43 +1300, @aasm_current_state=:closed> | |
D, [2013-03-29T01:15:43.391343 #26911] DEBUG -- : on_success: reset_failure_count #<CircuitBreaker::CircuitState:0x007f91b9849f98 @failure_count=1, @last_failure_time=2013-03-29 01:15:43 +1300, @aasm_current_state=:closed> | |
1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment