Class: OllamaAgent::Providers::CredentialPool

Inherits:
Object
  • Object
show all
Defined in:
lib/ollama_agent/providers/credential_pool.rb

Overview

Thread-safe pool of Credential objects with weighted round-robin selection.

The pool is the single source of truth for which credentials are available. It exposes:

- next_credential  — picks the next available credential (weighted RR)
- any_available?   — fast availability check used by CredentialRouter
- all_status       — full snapshot for TUI and telemetry

Examples:

pool = CredentialPool.new(credentials: [cred_a, cred_b, cred_c])
cred = pool.next_credential   # weighted round-robin
pool.any_available?           # => true / false

Instance Method Summary collapse

Constructor Details

#initialize(credentials:) ⇒ CredentialPool

Returns a new instance of CredentialPool.



20
21
22
23
24
# File 'lib/ollama_agent/providers/credential_pool.rb', line 20

def initialize(credentials:)
  @credentials = Array(credentials)
  @mutex       = Mutex.new
  @index       = 0
end

Instance Method Details

#aggregate_usageHash

Aggregate quota summary across all credentials for the same provider. Useful for the “Usage” TUI panel.

Returns:

  • (Hash)


76
77
78
79
80
81
82
83
84
# File 'lib/ollama_agent/providers/credential_pool.rb', line 76

def aggregate_usage
  all = @credentials.map { |c| c.quota_tracker.summary }
  {
    total_daily_tokens: all.sum { |s| s[:daily_tokens] },
    total_daily_requests: all.sum { |s| s[:daily_requests] },
    total_rpm: all.sum { |s| s[:rpm] },
    total_tpm: all.sum { |s| s[:tpm] }
  }
end

#all_statusArray<Hash>

Full status snapshot for the TUI providers panel.

Returns:

  • (Array<Hash>)


69
70
71
# File 'lib/ollama_agent/providers/credential_pool.rb', line 69

def all_status
  @credentials.map(&:status_summary)
end

#any_available?Boolean

Returns:

  • (Boolean)


53
54
55
# File 'lib/ollama_agent/providers/credential_pool.rb', line 53

def any_available?
  @credentials.any?(&:available?)
end

#first_available_key(provider) ⇒ String?

Find the first available API key for a given provider.

Parameters:

  • provider (String)

Returns:

  • (String, nil)


89
90
91
92
93
# File 'lib/ollama_agent/providers/credential_pool.rb', line 89

def first_available_key(provider)
  @mutex.synchronize do
    @credentials.find { |c| c.provider == provider.to_s && c.available? }&.api_key
  end
end

#near_exhaustion_idsArray<String>

Returns ids of credentials approaching quota exhaustion.

Returns:

  • (Array<String>)

    ids of credentials approaching quota exhaustion



58
59
60
# File 'lib/ollama_agent/providers/credential_pool.rb', line 58

def near_exhaustion_ids
  @credentials.select(&:near_exhaustion?).map(&:id)
end

#next_credentialCredential

Pick the next available credential using weighted round-robin.

Weighted RR: each credential is repeated ‘weight` times in the selection array. A credential with weight=2 receives roughly twice the traffic of one with weight=1.

Returns:

Raises:



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ollama_agent/providers/credential_pool.rb', line 34

def next_credential
  @mutex.synchronize do
    available = @credentials.select(&:available?)

    if available.empty?
      names = @credentials.map(&:id).join(", ")
      raise OllamaAgent::NoAvailableCredentialError,
            "All credentials exhausted or cooling down (pool: #{names})"
    end

    # Expand by weight so each slot in the array represents one "share"
    weighted = available.flat_map { |c| Array.new(c.weight, c) }
    cred     = weighted[@index % weighted.size]
    @index   = (@index + 1) % weighted.size
    cred
  end
end

#sizeInteger

Returns:

  • (Integer)


63
64
65
# File 'lib/ollama_agent/providers/credential_pool.rb', line 63

def size
  @credentials.size
end