Waits until a token is available for key, then consumes exactly one. Returns the
number of milliseconds spent waiting (0 if a token was immediately available) — useful
for the engine to surface "we are being held back" telemetry.
Returns a read-only snapshot of key's state (refilled to "now"). Creates the bucket if absent.
Additive increase: a call for key succeeded. Nudges the effective rate up by
SuccessRampPerCall, never above the configured TokensPerSec ceiling (AIMD recovery).
Multiplicative decrease: the source threw a 429 / rate-limit signal for key. Cuts the
effective rate by ThrottleBackoffFactor (floored at MinTokensPerSec) and, when a
Retry-After is supplied, freezes refills for that long so the bucket drains.
OptionalretryAfterMs: numberDrops all per-key state. Mainly for tests and engine teardown.
Adaptive per-key token-bucket rate limiter. See file header for the full design. One instance per engine; keys are IntegrationIDs (or any stable string).