Class: Legion::LLM::Router::HealthTracker
- Inherits:
-
Object
- Object
- Legion::LLM::Router::HealthTracker
- Includes:
- Legion::Logging::Helper
- Defined in:
- lib/legion/llm/router/health_tracker.rb
Constant Summary collapse
- OPEN_PENALTY =
-50
- LATENCY_THRESHOLD_MS =
5000- LATENCY_PENALTY_STEP =
-10
Instance Method Summary collapse
-
#adjustment(provider, offering_id: nil) ⇒ Object
Returns total priority adjustment for a provider.
-
#circuit_state(provider, offering_id: nil) ⇒ Object
Returns :closed, :open, or :half_open.
-
#initialize(window_seconds: 300, failure_threshold: 3, cooldown_seconds: 60) ⇒ HealthTracker
constructor
A new instance of HealthTracker.
-
#register_handler(signal, &block) ⇒ Object
Register a custom handler for a signal type.
-
#report(provider:, signal:, value:, metadata: {}, offering_id: nil) ⇒ Object
Thread-safe signal intake.
-
#reset(provider, offering_id: nil) ⇒ Object
Clears circuit and latency data for a single provider.
-
#reset_all ⇒ Object
Clears all state.
Constructor Details
#initialize(window_seconds: 300, failure_threshold: 3, cooldown_seconds: 60) ⇒ HealthTracker
Returns a new instance of HealthTracker.
14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/legion/llm/router/health_tracker.rb', line 14 def initialize(window_seconds: 300, failure_threshold: 3, cooldown_seconds: 60) @window_seconds = window_seconds @failure_threshold = failure_threshold @cooldown_seconds = cooldown_seconds @circuits = {} @latency_window = {} @handlers = {} @mutex = Mutex.new register_default_handlers end |
Instance Method Details
#adjustment(provider, offering_id: nil) ⇒ Object
Returns total priority adjustment for a provider. Combines circuit-breaker penalty and latency penalty.
52 53 54 55 56 |
# File 'lib/legion/llm/router/health_tracker.rb', line 52 def adjustment(provider, offering_id: nil) key = health_key(provider, offering_id) key = provider if offering_id && !tracked?(key) && tracked?(provider) circuit_adjustment(key) + latency_adjustment(key) end |
#circuit_state(provider, offering_id: nil) ⇒ Object
Returns :closed, :open, or :half_open.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/legion/llm/router/health_tracker.rb', line 59 def circuit_state(provider, offering_id: nil) key = health_key(provider, offering_id) key = provider if offering_id && !tracked?(key) && tracked?(provider) circuit = @circuits[key] return :closed if circuit.nil? if circuit[:state] == :open elapsed = Time.now - circuit[:opened_at] if elapsed >= @cooldown_seconds log.warn("Circuit open->half_open for provider=#{key} (cooldown elapsed)") return :half_open end end circuit[:state] end |
#register_handler(signal, &block) ⇒ Object
Register a custom handler for a signal type.
28 29 30 |
# File 'lib/legion/llm/router/health_tracker.rb', line 28 def register_handler(signal, &block) @handlers[signal.to_sym] = block end |
#report(provider:, signal:, value:, metadata: {}, offering_id: nil) ⇒ Object
Thread-safe signal intake. Dispatches to the registered handler if one exists.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/legion/llm/router/health_tracker.rb', line 33 def report(provider:, signal:, value:, metadata: {}, offering_id: nil) sym = signal.to_sym handler = @handlers[sym] return nil unless handler payload = { provider: health_key(provider, offering_id), provider_id: provider, offering_id: offering_id, signal: sym, value: value, metadata: , at: Time.now } @mutex.synchronize { handler.call(payload) } end |
#reset(provider, offering_id: nil) ⇒ Object
Clears circuit and latency data for a single provider.
77 78 79 80 81 82 83 |
# File 'lib/legion/llm/router/health_tracker.rb', line 77 def reset(provider, offering_id: nil) key = health_key(provider, offering_id) @mutex.synchronize do @circuits.delete(key) @latency_window.delete(key) end end |
#reset_all ⇒ Object
Clears all state.
86 87 88 89 90 91 |
# File 'lib/legion/llm/router/health_tracker.rb', line 86 def reset_all @mutex.synchronize do @circuits.clear @latency_window.clear end end |