Class: NatsWork::CircuitBreaker

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

Constant Summary collapse

STATES =
%i[closed open half_open].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ CircuitBreaker

Returns a new instance of CircuitBreaker.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/natswork/circuit_breaker.rb', line 12

def initialize(options = {})
  @failure_threshold = options[:failure_threshold] || 5
  @success_threshold = options[:success_threshold] || 2
  @timeout = options[:timeout] || 60
  @reset_timeout = options[:reset_timeout] || 60

  @state = :closed
  @failure_count = 0
  @success_count = 0
  @last_failure_time = nil
  @mutex = Mutex.new
  @on_open = options[:on_open]
  @on_close = options[:on_close]
  @on_half_open = options[:on_half_open]
end

Instance Attribute Details

#failure_countObject (readonly)

Returns the value of attribute failure_count.



10
11
12
# File 'lib/natswork/circuit_breaker.rb', line 10

def failure_count
  @failure_count
end

#last_failure_timeObject (readonly)

Returns the value of attribute last_failure_time.



10
11
12
# File 'lib/natswork/circuit_breaker.rb', line 10

def last_failure_time
  @last_failure_time
end

#stateObject (readonly)

Returns the value of attribute state.



10
11
12
# File 'lib/natswork/circuit_breaker.rb', line 10

def state
  @state
end

Instance Method Details

#callObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/natswork/circuit_breaker.rb', line 28

def call
  @mutex.synchronize do
    case @state
    when :open
      raise CircuitOpenError, 'Circuit breaker is open' unless can_attempt_reset?

      transition_to(:half_open)

    when :half_open
      # Allow the attempt in half-open state
    when :closed
      # Allow the attempt in closed state
    end
  end

  begin
    result = yield
    on_success
    result
  rescue StandardError => e
    on_failure(e)
    raise
  end
end

#closed?Boolean

Returns:

  • (Boolean)


53
54
55
# File 'lib/natswork/circuit_breaker.rb', line 53

def closed?
  @state == :closed
end

#half_open?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/natswork/circuit_breaker.rb', line 61

def half_open?
  @state == :half_open
end

#open?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/natswork/circuit_breaker.rb', line 57

def open?
  @state == :open
end

#resetObject



65
66
67
68
69
70
71
72
# File 'lib/natswork/circuit_breaker.rb', line 65

def reset
  @mutex.synchronize do
    @failure_count = 0
    @success_count = 0
    @last_failure_time = nil
    transition_to(:closed)
  end
end

#statsObject



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/natswork/circuit_breaker.rb', line 80

def stats
  @mutex.synchronize do
    {
      state: @state,
      failure_count: @failure_count,
      success_count: @success_count,
      last_failure_time: @last_failure_time,
      time_until_retry: time_until_retry
    }
  end
end

#tripObject



74
75
76
77
78
# File 'lib/natswork/circuit_breaker.rb', line 74

def trip
  @mutex.synchronize do
    transition_to(:open)
  end
end