Class: CircuitBreaker::CircuitHandler
- Inherits:
-
Object
- Object
- CircuitBreaker::CircuitHandler
- Defined in:
- lib/circuit_breaker/circuit_handler.rb
Overview
CircuitHandler is stateless, so the circuit_state gets mixed in with the calling object.
Constant Summary collapse
- DEFAULT_FAILURE_THRESHOLD =
5
- DEFAULT_FAILURE_TIMEOUT =
5
Instance Attribute Summary collapse
-
#failure_threshold ⇒ Object
The number of failures needed to trip the breaker.
-
#failure_timeout ⇒ Object
The period of time in seconds before attempting to reset the breaker.
-
#logger ⇒ Object
Optional logger.
Instance Method Summary collapse
-
#handle(circuit_state, method, *args) ⇒ Object
Handles the method covered by the circuit breaker.
-
#initialize(logger = nil) ⇒ CircuitHandler
constructor
A new instance of CircuitHandler.
-
#is_failure_threshold_reached(circuit_state) ⇒ Object
Returns true when the number of failures is sufficient to trip the breaker, false otherwise.
-
#is_timeout_exceeded(circuit_state) ⇒ Object
Returns true if enough time has elapsed since the last failure time, false otherwise.
-
#is_tripped(circuit_state) ⇒ Object
Returns true if the circuit breaker is still open and the timeout has not been exceeded, false otherwise.
-
#new_circuit_state ⇒ Object
Returns a new CircuitState instance.
-
#on_circuit_open(circuit_state) ⇒ Object
Called when a call is made and the circuit is open.
-
#on_failure(circuit_state) ⇒ Object
Called when an individual failure happens.
-
#on_success(circuit_state) ⇒ Object
Called when an individual success happens.
Constructor Details
#initialize(logger = nil) ⇒ CircuitHandler
Returns a new instance of CircuitHandler.
27 28 29 30 31 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 27 def initialize(logger = nil) @logger = logger @failure_threshold = DEFAULT_FAILURE_THRESHOLD @failure_timeout = DEFAULT_FAILURE_TIMEOUT end |
Instance Attribute Details
#failure_threshold ⇒ Object
The number of failures needed to trip the breaker.
12 13 14 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 12 def failure_threshold @failure_threshold end |
#failure_timeout ⇒ Object
The period of time in seconds before attempting to reset the breaker.
17 18 19 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 17 def failure_timeout @failure_timeout end |
#logger ⇒ Object
Optional logger.
22 23 24 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 22 def logger @logger end |
Instance Method Details
#handle(circuit_state, method, *args) ⇒ Object
Handles the method covered by the circuit breaker.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 43 def handle(circuit_state, method, *args) 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 = method[*args] on_success(circuit_state) rescue Exception on_failure(circuit_state) raise end return out end |
#is_failure_threshold_reached(circuit_state) ⇒ Object
Returns true when the number of failures is sufficient to trip the breaker, false otherwise.
62 63 64 65 66 67 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 62 def is_failure_threshold_reached(circuit_state) out = (circuit_state.failure_count > failure_threshold) @logger.debug("is_failure_threshold_reached: #{circuit_state.failure_count} > #{failure_threshold} == #{out}") if @logger return out end |
#is_timeout_exceeded(circuit_state) ⇒ Object
Returns true if enough time has elapsed since the last failure time, false otherwise.
72 73 74 75 76 77 78 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 72 def is_timeout_exceeded(circuit_state) now = Time.now time_since = now - circuit_state.last_failure_time @logger.debug("timeout_exceeded: time since last failure = #{time_since.inspect}") if @logger return time_since >= failure_timeout end |
#is_tripped(circuit_state) ⇒ Object
Returns true if the circuit breaker is still open and the timeout has not been exceeded, false otherwise.
84 85 86 87 88 89 90 91 92 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 84 def is_tripped(circuit_state) if circuit_state.open? && is_timeout_exceeded(circuit_state) @logger.debug("is_tripped: attempting reset into half open state for #{circuit_state.inspect}") if @logger circuit_state.attempt_reset end return circuit_state.open? end |
#new_circuit_state ⇒ Object
Returns a new CircuitState instance.
36 37 38 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 36 def new_circuit_state ::CircuitBreaker::CircuitState.new end |
#on_circuit_open(circuit_state) ⇒ Object
Called when a call is made and the circuit is open. Raises a CircuitBrokenException exception.
129 130 131 132 133 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 129 def on_circuit_open(circuit_state) @logger.debug("on_circuit_open: raising for #{circuit_state.inspect}") if @logger raise CircuitBreaker::CircuitBrokenException.new("Circuit broken, please wait for timeout", circuit_state) end |
#on_failure(circuit_state) ⇒ Object
Called when an individual failure happens.
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 114 def on_failure(circuit_state) @logger.debug("on_failure: circuit_state = #{circuit_state.inspect}") if @logger circuit_state.increment_failure_count if is_failure_threshold_reached(circuit_state) || circuit_state.half_open? # Set us into a closed state. @logger.debug("on_failure: tripping circuit breaker #{circuit_state.inspect}") if @logger circuit_state.trip end end |
#on_success(circuit_state) ⇒ Object
Called when an individual success happens.
97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/circuit_breaker/circuit_handler.rb', line 97 def on_success(circuit_state) @logger.debug("on_success: #{circuit_state.inspect}") if @logger if circuit_state.closed? @logger.debug("on_success: reset_failure_count #{circuit_state.inspect}") if @logger circuit_state.reset_failure_count end if circuit_state.half_open? @logger.debug("on_success: reset circuit #{circuit_state.inspect}") if @logger circuit_state.reset end end |