Whether any key exists at all.
Optional config: ApiKeyPoolConfigLoads the persisted state once, when the pool has a store and an id; the
providers await it in initialize() before the first next(). Resolves
at once without a store. A load that throws, or that does not answer
within loadTimeoutMs, leaves a fresh state and logs one warning; rows
that arrive after the deadline are ignored.
The next key by the strategy. A single-key pool returns its key. With
several keys: a usable key, or, when none is usable, the resting key
whose rest ends first (a throttled key still goes out and its answer
updates the state; a failed key never does); '' when every key is
failed, which the provider turns into its all-keys-failed error. A failed
key whose recheck is due has a probe scheduled here, off the request path.
next(), and when it finds no key to hand out while a probe of a failed
key is in flight (one this draw just started because its recheck came
due, or the timer's), waits for the next probe to settle and draws again,
for as long as no key can be drawn and a probe is still running, each
probe bounded by probeTimeoutMs. So the first request after a recheck
comes due is served by the first key that came back, instead of failing
on a probe that was about to pass and re-opening the provider health
breaker for another window, and without waiting for the probe of another
key that hangs. The caller's signal ends the wait at once; the draw
then answers '', and the provider reports the abort. The providers
draw their first key of a request through it.
Optional signal: AbortSignalRecords a key-scoped failure. quota rests the key (Retry-After when
given, else the cooldown); auth and billing take it out until a probe
passes, or until the recheck delay has run when there is no probe. A
result whose at is older than the key's last recorded result is
ignored, so an old answer never undoes a newer one. An auth or billing
failure counts toward the recheck delay only when its request started
after the key's previous failure was recorded, strictly later: the
answers of requests that were in flight together (each drew the key
while it was ok, so each started no later than that record) count once.
Optional detail: { Optional retryOptional status?: numberOptional at?: numberProbes failed keys on the pool's own clock: one timer per pool, armed to
the soonest nextRecheckAt of a failed key (so the first probe runs
recheckMs after the failure, where an interval fixed at start could run
it up to twice that late) and at the latest intervalMs ahead, re-armed
after each run, each failure, each success and each probe. A second call
replaces the first; the returned function stops it. The timer never
keeps the process alive and holds the pool weakly where the runtime has
WeakRef: a pool nothing else holds (a provider dropped without
shutdown(), a manager evicted from createProviderManager()'s cache)
ends its timer at its next run instead of being kept alive by it.
Ends the pool's work for a host that is shutting down: stops the recheck
timer, waits for the probes in flight (each bounded by the probe
timeout), then writes every pending state change (bounded by
storeTimeoutMs), so what a probe found during shutdown is kept and a
store that does not answer cannot hold the host. The providers'
shutdown() calls it.
Writes every pending state change now and waits for the writes in
flight, at most storeTimeoutMs, so a host that is shutting down keeps
the keys' standing without hanging on a store that does not answer (one
warning when the deadline passes); the providers' shutdown() calls it.
Resolves at once without a store.
Number of keys in the pool (including resting and failed ones).