Interface RateLimiter<T>
- Type Parameters:
T- the amount type:Integerfor token counts,Voidfor unit permits, a routing key for multi-bucket limiters
- All Known Implementing Classes:
AbstractRateLimiter, CountingGate, DatabaseGate, ElasticWindowRateLimiter, EPORateLimiter, HttpConnectionGate, MemoryPressureGate, ModelGate, PubMedRateLimiter, STDIOEndpointRateLimiter, TokenBucketRateLimiter, UsptoOdpRateLimiter
public interface RateLimiter<T>
One admission account: a resource counter with a replenishment kind that a job's
Demand names and that Admission debits.
An account never blocks and never parks anyone. The wait belongs to Admission,
which evaluates a job's whole demand as one conjunctive guard and takes every entry in one
critical section or none of them. The account answers three questions about amounts and
performs two movements:
fits(List, List): wouldminefit right now withreservedAheadset aside. Pure with respect to admission state (clocked accounts may advance their own bookkeeping). Refusal is judged onminealone: throw anUncorrectableRuntimeLLMExceptionwhenminecan never fit under the current configuration or when the account is refusing everyone; whenminefits alone but not together withreservedAhead, the answer isfalse.tryTake(List, List): the debit. TakemineifmineandreservedAheadfit together, atomically under the account's own lock, so a cap or circuit change on a client thread cannot land between the check and the take.give(List): the credit, at close forRateLimiter.Replenishment.RELEASEaccounts, at rollback and as compensation inside a failed grant for every account.earliestFit(List, List): theSystem.nanoTime()instant at whichfits(List, List)would become true from the clock alone, ornullwhen only an external event can change the answer.
mine are the asking job's amounts on this account; reservedAhead are the
amounts the head of the admission queue holds reserved on it, empty for the head itself.
Each account decides how amounts combine: tokens sum, unit permits count, a router routes
each to its bucket, a predicate account ignores them. Amount lists may contain null
for Void-typed accounts.
- Since:
- 0.1 (2025-11-14)
- Author:
- Andrey Santrosyan
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic enumHow a permit taken from this limiter comes back, which decides whetherAdmissionmay return it when the job finishes. -
Method Summary
Modifier and TypeMethodDescriptionaccountFor(T amount) The identity the given amount debits: this limiter for a plain account, the routed bucket for a router.earliestFit(List<T> mine, List<T> reservedAhead) TheSystem.nanoTime()instant at whichfits(List, List)would become true for these lists from the clock alone;nullwhen only an external event can change the answer - always forRateLimiter.Replenishment.RELEASEaccounts, and for any account whenmineplusreservedAheadexceeds its capacity.booleanWouldminefit right now withreservedAheadset aside.voidCredits previously taken amounts.default voidobserveHeld(IntSupplier held) Installs a lock-free view of how many jobs admission is holding on this account right now: the waiters this account has refused and not yet released, which is this account's own line and nobody else's.voidonCapacityChange(Runnable wake) Installs the single wake this account runs after any self-change that can only increase capacity: a throttle relaxation, a cap raised from headers, a circuit closing, a pushed fleet allotment.voidonRateLimitError(UpstreamFailure failure) Notifies the rate limiter that an upstream request failed.default voidonRateLimitError(UpstreamFailure failure, T input) Per-input variant ofonRateLimitError(UpstreamFailure).voidNotifies the rate limiter of a successful operation.default voidNotifies the rate limiter of a successful operation, scoped to the specific input that was acquired.Which replenishment model this limiter follows.default booleanWhether this rate limiter's operations require HTTP connections.booleanTakesmineifmineandreservedAheadfit together; the check and the debit are one atomic step under the account's own lock.
-
Method Details
-
replenishment
RateLimiter.Replenishment replenishment()Which replenishment model this limiter follows. Deliberately has no default: the answer is a property of the limiter's nature, and guessing it wrong is silent in both directions - a leaked permit one way, a disabled rate limit the other. -
fits
Wouldminefit right now withreservedAheadset aside.- Throws:
UncorrectableRuntimeLLMException- whenminecan never fit under the current configuration, or when the account is refusing everyone
-
tryTake
TakesmineifmineandreservedAheadfit together; the check and the debit are one atomic step under the account's own lock.- Returns:
- true when taken, false when the amounts do not fit at this instant
- Throws:
UncorrectableRuntimeLLMException- under the same conditions asfits(List, List)
-
give
Credits previously taken amounts. For aRateLimiter.Replenishment.TIMEaccount this is a refund of a debit whose request never went upstream. -
earliestFit
TheSystem.nanoTime()instant at whichfits(List, List)would become true for these lists from the clock alone;nullwhen only an external event can change the answer - always forRateLimiter.Replenishment.RELEASEaccounts, and for any account whenmineplusreservedAheadexceeds its capacity. A past instant means now. -
onCapacityChange
Installs the single wake this account runs after any self-change that can only increase capacity: a throttle relaxation, a cap raised from headers, a circuit closing, a pushed fleet allotment. The wake is a bare unpark of the admission evaluator and never re-enters an account or the monitor, so it may be run from anywhere, under any lock.nullclears the slot. Decreases never wake anyone. -
observeHeld
Installs a lock-free view of how many jobs admission is holding on this account right now: the waiters this account has refused and not yet released, which is this account's own line and nobody else's. An account that drains its line at a rate needs to know whether it has one: with nothing held here a lone arrival passes at once, with a line the releases are spaced, and a line held on some other account is not this account's to pace. Accounts whose answer does not depend on their line ignore this. -
accountFor
The identity the given amount debits: this limiter for a plain account, the routed bucket for a router. Head reservation, waiter counts and events all key on it. -
onSuccess
void onSuccess()Notifies the rate limiter of a successful operation. Used by adaptive strategies to relax throttling. -
onSuccess
Notifies the rate limiter of a successful operation, scoped to the specific input that was acquired. Default implementation delegates toonSuccess()for limiters that don't care about per-input bucketing. Multi-bucket limiters (e.g. one elastic window per upstream sub-service) override this to signal the correct bucket.- Parameters:
input- The same value that was passed as an amount in the demand
-
onRateLimitError
Notifies the rate limiter that an upstream request failed. Used by adaptive strategies to tighten throttling, and - just as importantly - to record what the upstream actually said, so anything the limiter subsequently emits can name the cause.- Parameters:
failure- the upstream's status and response detail; never null
-
onRateLimitError
Per-input variant ofonRateLimitError(UpstreamFailure). Default implementation delegates for limiters that don't care about per-input bucketing. Multi-bucket limiters override this to tighten only the bucket that failed.- Parameters:
failure- the upstream's status and response detail; never nullinput- The same value that was passed as an amount in the demand
-
requiresHttpConnection
default boolean requiresHttpConnection()Whether this rate limiter's operations require HTTP connections. A demand that names such a limiter also names the shared HTTP connection gate.- Returns:
- true if operations require HTTP, false otherwise
-