Class: RedisClient::CircuitBreaker

Inherits:
Object
  • Object
show all
Defined in:
lib/redis_client/circuit_breaker.rb

Defined Under Namespace

Modules: Middleware

Constant Summary collapse

OpenCircuitError =
Class.new(CannotConnectError)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(error_threshold:, error_timeout:, error_threshold_timeout: error_timeout, success_threshold: 0) ⇒ CircuitBreaker

Returns a new instance of CircuitBreaker.



23
24
25
26
27
28
29
30
31
32
# File 'lib/redis_client/circuit_breaker.rb', line 23

def initialize(error_threshold:, error_timeout:, error_threshold_timeout: error_timeout, success_threshold: 0)
  @error_threshold = Integer(error_threshold)
  @error_threshold_timeout = Float(error_threshold_timeout)
  @error_timeout = Float(error_timeout)
  @success_threshold = Integer(success_threshold)
  @errors = []
  @successes = 0
  @state = :closed
  @lock = Mutex.new
end

Instance Attribute Details

#error_thresholdObject (readonly)

Returns the value of attribute error_threshold.



21
22
23
# File 'lib/redis_client/circuit_breaker.rb', line 21

def error_threshold
  @error_threshold
end

#error_threshold_timeoutObject (readonly)

Returns the value of attribute error_threshold_timeout.



21
22
23
# File 'lib/redis_client/circuit_breaker.rb', line 21

def error_threshold_timeout
  @error_threshold_timeout
end

#error_timeoutObject (readonly)

Returns the value of attribute error_timeout.



21
22
23
# File 'lib/redis_client/circuit_breaker.rb', line 21

def error_timeout
  @error_timeout
end

#success_thresholdObject (readonly)

Returns the value of attribute success_threshold.



21
22
23
# File 'lib/redis_client/circuit_breaker.rb', line 21

def success_threshold
  @success_threshold
end

Instance Method Details

#protectObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/redis_client/circuit_breaker.rb', line 34

def protect
  if @state == :open
    refresh_state
  end

  case @state
  when :open
    raise OpenCircuitError, "Too many connection errors happened recently"
  when :closed
    begin
      yield
    rescue ConnectionError
      record_error
      raise
    end
  when :half_open
    begin
      result = yield
      record_success
      result
    rescue ConnectionError
      record_error
      raise
    end
  else
    raise "[BUG] RedisClient::CircuitBreaker unexpected @state (#{@state.inspect}})"
  end
end