aiokpl.token_bucket¶
token_bucket ¶
Multi-stream token bucket with growth-on-query semantics.
Mirrors aws/utils/token_bucket.h in the C++ KPL: a small fixed set of
independent token streams sharing one atomic try_take decision. Growth is
computed lazily — every query advances tokens by rate * (now - last)
capped at max_tokens. No background refill task, no time.sleep: pure
math, callable from sync or async code alike.
The atomicity contract on :meth:TokenBucket.try_take matches the C++
can_take + take pair: either every stream is debited, or none. This is
what makes the Limiter's "records and bytes within the same envelope"
guarantee possible.
TokenBucket ¶
TokenBucket(
streams: Sequence[tuple[float, float]],
*,
clock: Callable[[], float] = time.monotonic,
initial_full: bool = True,
)
Stateless-style multi-stream token bucket.
Growth is computed on demand: every query advances tokens by
rate * (now - last), capped at max_tokens. There is no background
refill task — pure math.
try_take([n0, n1, ...]) is atomic across all streams: it succeeds and
decrements every stream iff all streams currently have at least the
requested tokens, else it leaves the bucket untouched and returns False.
Source code in aiokpl/token_bucket.py
available ¶
try_take ¶
Atomic multi-stream debit.
Raises :class:ValueError if len(amounts) != stream_count or any
amount is negative. Returns True on success (every stream debited);
False on failure (no stream debited).