Class: Vmpooler::CircuitBreaker

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

Overview

Circuit breaker pattern implementation to prevent cascading failures when a provider becomes unresponsive or experiences repeated failures.

States:

  • CLOSED: Normal operation, requests flow through
  • OPEN: Provider is failing, reject requests immediately (fail fast)
  • HALF_OPEN: Testing if provider has recovered with limited requests

Defined Under Namespace

Classes: CircuitOpenError

Constant Summary collapse

STATES =
i[closed open half_open].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, logger:, metrics:, failure_threshold: 5, timeout: 30, half_open_attempts: 3) ⇒ CircuitBreaker

Initialize a new circuit breaker

Parameters:

  • name (String)

    Name for logging/metrics (e.g., "vsphere_provider")

  • logger (Object)

    Logger instance

  • metrics (Object)

    Metrics instance

  • failure_threshold (Integer) (defaults to: 5)

    Number of failures before opening circuit

  • timeout (Integer) (defaults to: 30)

    Seconds to wait in open state before testing (half-open)

  • half_open_attempts (Integer) (defaults to: 3)

    Number of successful test requests needed to close



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/vmpooler/circuit_breaker.rb', line 26

def initialize(name:, logger:, metrics:, failure_threshold: 5, timeout: 30, half_open_attempts: 3)
  @name = name
  @logger = logger
  @metrics = metrics
  @failure_threshold = failure_threshold
  @timeout = timeout
  @half_open_attempts = half_open_attempts

  @state = :closed
  @failure_count = 0
  @success_count = 0
  @last_failure_time = nil
  @mutex = Mutex.new
end

Instance Attribute Details

#failure_countObject (readonly)

Returns the value of attribute failure_count.



16
17
18
# File 'lib/vmpooler/circuit_breaker.rb', line 16

def failure_count
  @failure_count
end

#stateObject (readonly)

Returns the value of attribute state.



16
17
18
# File 'lib/vmpooler/circuit_breaker.rb', line 16

def state
  @state
end

#success_countObject (readonly)

Returns the value of attribute success_count.



16
17
18
# File 'lib/vmpooler/circuit_breaker.rb', line 16

def success_count
  @success_count
end

Instance Method Details

#allow_request?Boolean

Check if circuit allows requests

Returns:

  • (Boolean)

    true if circuit is closed or half-open



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/vmpooler/circuit_breaker.rb', line 61

def allow_request?
  @mutex.synchronize do
    case @state
    when :closed
      true
    when :half_open
      true
    when :open
      if should_attempt_reset?
        true
      else
        false
      end
    end
  end
end

#call { ... } ⇒ Object

Execute a block with circuit breaker protection

Yields:

  • Block to execute if circuit allows

Returns:

  • Result of the block

Raises:

  • CircuitOpenError if circuit is open and timeout hasn't elapsed



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/vmpooler/circuit_breaker.rb', line 46

def call
  check_state

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

#statusHash

Get current circuit breaker status

Returns:

  • (Hash)

    Status information



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

def status
  @mutex.synchronize do
    {
      name: @name,
      state: @state,
      failure_count: @failure_count,
      success_count: @success_count,
      last_failure_time: @last_failure_time,
      next_retry_time: next_retry_time
    }
  end
end