Class: Woods::Resilience::CircuitBreaker
- Inherits:
-
Object
- Object
- Woods::Resilience::CircuitBreaker
- Defined in:
- lib/woods/resilience/circuit_breaker.rb
Overview
Circuit breaker pattern for protecting external service calls.
Tracks failures and transitions between three states:
-
:closed — normal operation, calls pass through
-
:open — too many failures, calls are rejected immediately
-
:half_open — testing recovery, one call is allowed through
Instance Attribute Summary collapse
-
#state ⇒ Symbol
readonly
Current state — :closed, :open, or :half_open.
Instance Method Summary collapse
-
#call { ... } ⇒ Object
Execute a block through the circuit breaker.
-
#initialize(threshold: 5, reset_timeout: 60) ⇒ CircuitBreaker
constructor
A new instance of CircuitBreaker.
Constructor Details
#initialize(threshold: 5, reset_timeout: 60) ⇒ CircuitBreaker
Returns a new instance of CircuitBreaker.
39 40 41 42 43 44 45 46 |
# File 'lib/woods/resilience/circuit_breaker.rb', line 39 def initialize(threshold: 5, reset_timeout: 60) @threshold = threshold @reset_timeout = reset_timeout @state = :closed @failure_count = 0 @last_failure_time = nil @mutex = Mutex.new end |
Instance Attribute Details
#state ⇒ Symbol (readonly)
Returns Current state — :closed, :open, or :half_open.
35 36 37 |
# File 'lib/woods/resilience/circuit_breaker.rb', line 35 def state @state end |
Instance Method Details
#call { ... } ⇒ Object
Execute a block through the circuit breaker.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/woods/resilience/circuit_breaker.rb', line 54 def call(&block) # Phase 1: Check state under mutex @mutex.synchronize do case @state when :open unless monotonic_now - @last_failure_time >= @reset_timeout raise CircuitOpenError, "Circuit breaker is open (#{@failure_count} failures)" end @state = :half_open end end # Phase 2: Execute outside mutex result = block.call # Phase 3: Record success under mutex @mutex.synchronize { reset! } result rescue CircuitOpenError raise rescue StandardError => e # Phase 4: Record failure under mutex @mutex.synchronize { record_failure } raise e end |