Class: Logtide::CircuitBreaker

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

Overview

Circuit breaker around batch delivery (spec 002 section 7).

closed -> count consecutive failures; at threshold -> open open -> fail fast until reset_timeout has elapsed -> half-open half-open -> allow exactly one probe; success -> closed, failure -> open

A threshold of 0 disables the breaker entirely.

Instance Method Summary collapse

Constructor Details

#initialize(threshold:, reset_timeout:, clock: -> { Time.now }) ⇒ CircuitBreaker

Returns a new instance of CircuitBreaker.



12
13
14
15
16
17
18
19
20
21
# File 'lib/logtide/circuit_breaker.rb', line 12

def initialize(threshold:, reset_timeout:, clock: -> { Time.now })
  @threshold = threshold
  @reset_timeout = reset_timeout
  @clock = clock
  @mutex = Mutex.new
  @state = :closed
  @failures = 0
  @opened_at = nil
  @probe_in_flight = false
end

Instance Method Details

#allow?Boolean

Returns:

  • (Boolean)


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

def allow?
  return true if disabled?

  @mutex.synchronize do
    refresh
    case @state
    when :closed then true
    when :half_open
      if @probe_in_flight
        false
      else
        @probe_in_flight = true
        true
      end
    else
      false
    end
  end
end

#record_failureObject



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/logtide/circuit_breaker.rb', line 61

def record_failure
  return if disabled?

  @mutex.synchronize do
    if @state == :half_open
      open!
    else
      @failures += 1
      open! if @failures >= @threshold
    end
  end
end

#record_successObject



50
51
52
53
54
55
56
57
58
59
# File 'lib/logtide/circuit_breaker.rb', line 50

def record_success
  return if disabled?

  @mutex.synchronize do
    @state = :closed
    @failures = 0
    @opened_at = nil
    @probe_in_flight = false
  end
end

#stateObject



23
24
25
26
27
28
# File 'lib/logtide/circuit_breaker.rb', line 23

def state
  @mutex.synchronize do
    refresh
    @state
  end
end