Class InMemoryRateLimiter
- All Implemented Interfaces:
RateLimiter
A limit kept in this process's memory: a token bucket per key.
RateLimiter logins = new InMemoryRateLimiter(5, 60); // 5 a minute, per key
A key starts with permits tokens and gets them back at permits per
period, evenly: a client may spend them all at once and is then let through
at the steady rate, which is what "5 a minute" means to the person waiting.
The count is per process. A server run as several instances behind a
load balancer has one count in each, so a client is allowed up to the limit
times the number of instances. Where the limit is there to keep load down
that is usually what is wanted. Where it is a security bound -- attempts at
a password -- count somewhere the instances share, behind the RateLimiter
interface. The counts are also gone when the process restarts.
Memory is bounded: no more than a set number of keys are remembered, 100000 unless set. A key whose bucket has refilled is forgotten, since forgetting it changes nothing; past the bound the keys idle longest are forgotten early, which gives such a key its tokens back sooner than it earned them. A flood of distinct keys therefore costs a bounded amount of memory, and the most it buys the flooder is the full bucket a new key starts with anyway.
-
Constructor Summary
ConstructorsConstructorDescriptionInMemoryRateLimiter(int permits, long periodSeconds) InMemoryRateLimiter(int permits, long periodSeconds, int maxKeys) -
Method Summary
Modifier and TypeMethodDescriptionA limiter in this process with counts of its own, read on the same clock; the name is not needed to keep them apart.voidForgets what was counted underkey, so the next request under it is counted from nothing.longretryAfterSeconds(String key) How many seconds a request just refused underkeyshould wait before trying again: what itsRetry-Aftersays.voidReads the time fromclockinstead of the machine.intsize()How many keys are remembered now.booleantryAcquire(String key) Counts one request underkey.
-
Constructor Details
-
InMemoryRateLimiter
public InMemoryRateLimiter(int permits, long periodSeconds) - Parameters:
permits- how many requests a key may make in a periodperiodSeconds- the length of the period
-
InMemoryRateLimiter
public InMemoryRateLimiter(int permits, long periodSeconds, int maxKeys) - Parameters:
maxKeys- the most keys remembered at once
-
-
Method Details
-
derive
A limiter in this process with counts of its own, read on the same clock; the name is not needed to keep them apart.- Specified by:
derivein interfaceRateLimiter- Parameters:
name- what keeps the new limiter's counts apartpermits- how many requests a key may make in a periodperiodSeconds- the length of the period
-
setClock
Reads the time fromclockinstead of the machine. -
size
public int size()How many keys are remembered now. -
tryAcquire
Description copied from interface:RateLimiterCounts one request underkey.- Specified by:
tryAcquirein interfaceRateLimiter- Returns:
- whether the request is within the limit
-
reset
Description copied from interface:RateLimiterForgets what was counted under
key, so the next request under it is counted from nothing.A bound on wrong guesses uses this: the guess is counted before it is looked at, so that guesses made together cannot each be let through as the last one, and a right one hands the count back. A limiter that cannot forget does nothing here, which is what it does unless it says more; a right guess then costs what a wrong one does.
- Specified by:
resetin interfaceRateLimiter
-
retryAfterSeconds
Description copied from interface:RateLimiterHow many seconds a request just refused underkeyshould wait before trying again: what itsRetry-Aftersays. One second unless the limiter knows better.- Specified by:
retryAfterSecondsin interfaceRateLimiter
-