Class: Legion::LLM::Router::HealthTracker

Inherits:
Object
  • Object
show all
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

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) ⇒ Object

Returns total priority adjustment for a provider. Combines circuit-breaker penalty and latency penalty.



44
45
46
# File 'lib/legion/llm/router/health_tracker.rb', line 44

def adjustment(provider)
  circuit_adjustment(provider) + latency_adjustment(provider)
end

#circuit_state(provider) ⇒ Object

Returns :closed, :open, or :half_open.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/legion/llm/router/health_tracker.rb', line 49

def circuit_state(provider)
  circuit = @circuits[provider]
  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=#{provider} (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: {}) ⇒ Object

Thread-safe signal intake. Dispatches to the registered handler if one exists.



33
34
35
36
37
38
39
40
# File 'lib/legion/llm/router/health_tracker.rb', line 33

def report(provider:, signal:, value:, metadata: {})
  sym     = signal.to_sym
  handler = @handlers[sym]
  return nil unless handler

  payload = { provider: provider, signal: sym, value: value, metadata: , at: Time.now }
  @mutex.synchronize { handler.call(payload) }
end

#reset(provider) ⇒ Object

Clears circuit and latency data for a single provider.



65
66
67
68
69
70
# File 'lib/legion/llm/router/health_tracker.rb', line 65

def reset(provider)
  @mutex.synchronize do
    @circuits.delete(provider)
    @latency_window.delete(provider)
  end
end

#reset_allObject

Clears all state.



73
74
75
76
77
78
# File 'lib/legion/llm/router/health_tracker.rb', line 73

def reset_all
  @mutex.synchronize do
    @circuits.clear
    @latency_window.clear
  end
end