module SwitchGear::CircuitBreaker
Public Instance Methods
@param failure [SwitchGear::CircuitBreaker::Failure] a list of failures @return [void]
# File lib/switch_gear/circuit_breaker.rb, line 57 def add_failure(failure) must_implement(:add_failure) end
Calls the circuit proc/lambda if the circuit is closed or half-open.
@param args [Array<Object>] Any number of Objects to be called with the circuit block. @return [Void, SwitchGear::CircuitBreaker::Open] No usable return value if successful, but will raise an error if failure_limit is reached or if the circuit is open
# File lib/switch_gear/circuit_breaker.rb, line 13 def call(*args) check_reset_timeout raise OpenError if open? do_run(args, &circuit) end
@return [Boolean] Whether the circuit is closed
# File lib/switch_gear/circuit_breaker.rb, line 35 def closed? state == :closed end
@return [Integer] The count of current failures
# File lib/switch_gear/circuit_breaker.rb, line 25 def failure_count failures.size end
@return [Array<SwitchGear::CircuitBreaker::Failure>] a list of current failures
# File lib/switch_gear/circuit_breaker.rb, line 45 def failures must_implement(:failures) end
@param failure [Array<SwitchGear::CircuitBreaker::Failure>] a list of failures @return [void]
# File lib/switch_gear/circuit_breaker.rb, line 51 def failures=(failure) must_implement(:failures=) end
@return [Boolean] Whether the circuit is half-open
# File lib/switch_gear/circuit_breaker.rb, line 40 def half_open? state == :half_open end
@return most recent failure [SwitchGear::CircuitBreaker::Failure]
# File lib/switch_gear/circuit_breaker.rb, line 20 def most_recent_failure failures.last end
@return [Boolean] Whether the circuit is open
# File lib/switch_gear/circuit_breaker.rb, line 30 def open? state == :open end
@return [Symbol] - either :open, :closed, :half-open
# File lib/switch_gear/circuit_breaker.rb, line 62 def state must_implement(:state) end
@param state [Symbol] - either :open, :closed, :half-open @return [void]
# File lib/switch_gear/circuit_breaker.rb, line 68 def state=(state) must_implement(:state=) end
Private Instance Methods
# File lib/switch_gear/circuit_breaker.rb, line 85 def check_reset_timeout return if !open? if failure_count == 0 || reset_period_lapsed? self.state = :half_open end end
# File lib/switch_gear/circuit_breaker.rb, line 78 def do_run(args) yield *args reset_failures rescue => e handle_failure(e) end
# File lib/switch_gear/circuit_breaker.rb, line 102 def handle_failure(e) failure = Failure.new(e) add_failure(failure) logger.warn failure.to_s if half_open? || failure_count >= failure_limit self.state = :open else self.state = :closed end end
# File lib/switch_gear/circuit_breaker.rb, line 74 def must_implement(arg) raise NotImplementedError.new("You must implement #{arg}.") end
# File lib/switch_gear/circuit_breaker.rb, line 96 def reset_failures self.failures = [] self.state = :closed logger.info "Circuit closed" end
# File lib/switch_gear/circuit_breaker.rb, line 92 def reset_period_lapsed? (Time.now.utc - most_recent_failure.timestamp) > reset_timeout end
# File lib/switch_gear/circuit_breaker.rb, line 113 def run_validations logger_methods = [:debug, :info, :warn, :error] if !logger_methods.all? { |e| logger.respond_to?(e) } raise NotImplementedError.new("Your logger must respond to #{logger_methods}") end if !circuit.respond_to?(:call) raise NotImplementedError.new("Your circuit must respond to #call") end end