Class: Rester::Utils::CircuitBreaker

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

Defined Under Namespace

Classes: CircuitOpenError, Error

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}, &block) ⇒ CircuitBreaker

Returns a new instance of CircuitBreaker.



14
15
16
17
18
19
20
21
# File 'lib/rester/utils/circuit_breaker.rb', line 14

def initialize(opts={}, &block)
  @_synchronizer = Mutex.new
  @_retry_lock = Mutex.new
  self.threshold = opts[:threshold]
  self.retry_period = opts[:retry_period]
  @block = block
  reset
end

Instance Attribute Details

#blockObject (readonly)

Returns the value of attribute block.



9
10
11
# File 'lib/rester/utils/circuit_breaker.rb', line 9

def block
  @block
end

#failure_countObject (readonly)

Returns the value of attribute failure_count.



11
12
13
# File 'lib/rester/utils/circuit_breaker.rb', line 11

def failure_count
  @failure_count
end

#last_failed_atObject (readonly)

Returns the value of attribute last_failed_at.



12
13
14
# File 'lib/rester/utils/circuit_breaker.rb', line 12

def last_failed_at
  @last_failed_at
end

#retry_periodObject

Returns the value of attribute retry_period.



8
9
10
# File 'lib/rester/utils/circuit_breaker.rb', line 8

def retry_period
  @retry_period
end

#thresholdObject

Returns the value of attribute threshold.



7
8
9
# File 'lib/rester/utils/circuit_breaker.rb', line 7

def threshold
  @threshold
end

Instance Method Details

#call(*args) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rester/utils/circuit_breaker.rb', line 52

def call(*args)
  if closed?
    _call(*args)
  elsif half_open? && @_retry_lock.try_lock
    # Ensure only one thread can retry.
    begin
      _call(*args)
    ensure
      @_retry_lock.unlock
    end
  else
    fail CircuitOpenError
  end
end

#closed?Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/rester/utils/circuit_breaker.rb', line 31

def closed?
  !reached_threshold?
end

#half_open?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/rester/utils/circuit_breaker.rb', line 35

def half_open?
  !closed? && retry_period_passed?
end

#on_close(&block) ⇒ Object



27
28
29
# File 'lib/rester/utils/circuit_breaker.rb', line 27

def on_close(&block)
  _callbacks[:close] = block
end

#on_open(&block) ⇒ Object



23
24
25
# File 'lib/rester/utils/circuit_breaker.rb', line 23

def on_open(&block)
  _callbacks[:open] = block
end

#open?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/rester/utils/circuit_breaker.rb', line 39

def open?
  !closed? && !half_open?
end

#reached_threshold?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/rester/utils/circuit_breaker.rb', line 43

def reached_threshold?
  failure_count >= threshold
end

#resetObject



67
68
69
70
71
72
# File 'lib/rester/utils/circuit_breaker.rb', line 67

def reset
  _synchronize do
    @failure_count = 0
    @last_failed_at = nil
  end
end

#retry_period_passed?Boolean

Returns:

  • (Boolean)


47
48
49
50
# File 'lib/rester/utils/circuit_breaker.rb', line 47

def retry_period_passed?
  lf_at = last_failed_at
  !lf_at || (Time.now - lf_at) > retry_period
end