Class: HTM::CircuitBreaker
- Inherits:
-
Object
- Object
- HTM::CircuitBreaker
- Defined in:
- lib/htm/circuit_breaker.rb
Overview
Circuit Breaker - Prevents cascading failures from external LLM services
Implements the circuit breaker pattern to protect against repeated failures when calling external LLM APIs for embeddings or tag extraction.
States:
-
:closed - Normal operation, requests flow through
-
:open - Circuit tripped, requests fail fast with CircuitBreakerOpenError
-
:half_open - Testing if service recovered, allows limited requests
Constant Summary collapse
- DEFAULT_FAILURE_THRESHOLD =
Default configuration
5- DEFAULT_RESET_TIMEOUT =
Failures before opening circuit
60- DEFAULT_HALF_OPEN_MAX_CALLS =
Seconds before trying half-open
3
Instance Attribute Summary collapse
-
#failure_count ⇒ Object
readonly
Returns the value of attribute failure_count.
-
#last_failure_time ⇒ Object
readonly
Returns the value of attribute last_failure_time.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Instance Method Summary collapse
-
#call { ... } ⇒ Object
Execute a block with circuit breaker protection.
-
#closed? ⇒ Boolean
Check if circuit is currently closed (normal operation).
-
#half_open? ⇒ Boolean
Check if circuit is in half-open state (testing recovery).
-
#initialize(name:, failure_threshold: DEFAULT_FAILURE_THRESHOLD, reset_timeout: DEFAULT_RESET_TIMEOUT, half_open_max_calls: DEFAULT_HALF_OPEN_MAX_CALLS) ⇒ CircuitBreaker
constructor
Initialize a new circuit breaker.
-
#open? ⇒ Boolean
Check if circuit is currently open.
-
#reset! ⇒ void
Manually reset the circuit breaker to closed state.
-
#stats ⇒ Hash
Get current circuit breaker statistics.
Constructor Details
#initialize(name:, failure_threshold: DEFAULT_FAILURE_THRESHOLD, reset_timeout: DEFAULT_RESET_TIMEOUT, half_open_max_calls: DEFAULT_HALF_OPEN_MAX_CALLS) ⇒ CircuitBreaker
Initialize a new circuit breaker
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/htm/circuit_breaker.rb', line 42 def initialize( name:, failure_threshold: DEFAULT_FAILURE_THRESHOLD, reset_timeout: DEFAULT_RESET_TIMEOUT, half_open_max_calls: DEFAULT_HALF_OPEN_MAX_CALLS ) @name = name @failure_threshold = failure_threshold @reset_timeout = reset_timeout @half_open_max_calls = half_open_max_calls @state = :closed @failure_count = 0 @success_count = 0 @last_failure_time = nil @mutex = Mutex.new end |
Instance Attribute Details
#failure_count ⇒ Object (readonly)
Returns the value of attribute failure_count.
28 29 30 |
# File 'lib/htm/circuit_breaker.rb', line 28 def failure_count @failure_count end |
#last_failure_time ⇒ Object (readonly)
Returns the value of attribute last_failure_time.
28 29 30 |
# File 'lib/htm/circuit_breaker.rb', line 28 def last_failure_time @last_failure_time end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
28 29 30 |
# File 'lib/htm/circuit_breaker.rb', line 28 def name @name end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
28 29 30 |
# File 'lib/htm/circuit_breaker.rb', line 28 def state @state end |
Instance Method Details
#call { ... } ⇒ Object
Execute a block with circuit breaker protection
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/htm/circuit_breaker.rb', line 67 def call @mutex.synchronize do case @state when :open check_reset_timeout if @state == :open HTM.logger.warn "CircuitBreaker[#{@name}]: Circuit is OPEN, failing fast" raise CircuitBreakerOpenError, "Circuit breaker '#{@name}' is open. Service unavailable." end end end begin result = yield record_success result rescue StandardError => e record_failure(e) raise end end |
#closed? ⇒ Boolean
Check if circuit is currently closed (normal operation)
101 102 103 |
# File 'lib/htm/circuit_breaker.rb', line 101 def closed? @mutex.synchronize { @state == :closed } end |
#half_open? ⇒ Boolean
Check if circuit is in half-open state (testing recovery)
109 110 111 |
# File 'lib/htm/circuit_breaker.rb', line 109 def half_open? @mutex.synchronize { @state == :half_open } end |
#open? ⇒ Boolean
Check if circuit is currently open
93 94 95 |
# File 'lib/htm/circuit_breaker.rb', line 93 def open? @mutex.synchronize { @state == :open } end |
#reset! ⇒ void
This method returns an undefined value.
Manually reset the circuit breaker to closed state
117 118 119 120 121 122 123 124 125 |
# File 'lib/htm/circuit_breaker.rb', line 117 def reset! @mutex.synchronize do @state = :closed @failure_count = 0 @success_count = 0 @last_failure_time = nil HTM.logger.info "CircuitBreaker[#{@name}]: Manually reset to CLOSED" end end |
#stats ⇒ Hash
Get current circuit breaker statistics
131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/htm/circuit_breaker.rb', line 131 def stats @mutex.synchronize do { name: @name, state: @state, failure_count: @failure_count, success_count: @success_count, last_failure_time: @last_failure_time, failure_threshold: @failure_threshold, reset_timeout: @reset_timeout } end end |