public class TokenTemporalBucket extends TemporalBucket
This class represents a token bucket system. One instance represents one recurring bucket with a certain limit of tokens per timespan.
A circular buffer keeps track of tokens. The value of each buffer index represents the number of requests sent during that time period and as time passes, old indices are zeroed and the current index advances. The entire length of the buffer minus one represents a entire timespan (each index represents a fraction of the total timespan). The extra index prevents violations due to bucket misalignment. A rolling total is kept of the buffer's contents.
When trying to obtain a token, we first check the rolling total is less than the limit. If so, we obtain a token by incrementing the rolling total and incrementing the buffer's current index.
The length of the buffer is one more than the temporal factor supplied to the constructor. The temporal factor represents the multiplicative increase in temporal resolution provided with more buffer indices.
Additionally, a non-zero spreading factor can be provided to prevent a single index from supplying all of a timespan's tokens. A spreading factor of 0.0 means no spreading, a factor of 0.5 means each index can supply up to half of the tokens, and a factor of 1.0 means tokens will be evenly supplied by all indices (provided there is enough demand).
Checking the availability of tokens is done using the getDelay()
method. Tokens are obtained
using the TemporalBucket.getToken()
method. Both these methods are synchronized on the bucket instance. Because
the state of the bucket may change if there are multiple threads, it is best to call these methods in a
synchronized block, as shown below.
TokenTemporalBucket bucket = ...;
while (true) {
long delay;
synchronized (bucket) {
delay = bucket.getDelay();
if (delay == -1) {
bucket.getToken();
break;
}
}
// Waiting is done outside of the synchronized block.
Thread.sleep(delay);
}
// Token is obtained.
...
Constructor and Description |
---|
TokenTemporalBucket(long timespan,
int totalLimit,
int temporalFactor,
float spreadFactor,
float totalLimitFactor)
Creates a instance using System::currentTimeMillis as the time supplier.
|
TokenTemporalBucket(long timespan,
int totalLimit,
int temporalFactor,
float spreadFactor,
float totalLimitFactor,
Supplier<Long> timeSupplier)
Creates a instance with a custom time supplier.
|
Modifier and Type | Method and Description |
---|---|
boolean |
equals(Object obj) |
long |
getDelay()
Get the approximate delay til the next available token, or -1 if a token is available.
|
long |
getTimespan()
Get the timespan of this bucket in milliseconds.
|
boolean |
getTokens(int n)
Gets n tokens, regardless of whether they are available.
|
int |
getTotalLimit()
Get the total limit of this bucket per timespan.
|
int |
hashCode()
Returns the default hashCode() which is the memory address.
|
getAllTokensOrDelay, getToken, isEquivalent, toLimitString
public TokenTemporalBucket(long timespan, int totalLimit, int temporalFactor, float spreadFactor, float totalLimitFactor)
timespan
- The time per bucket in milliseconds.totalLimit
- The maximum number of tokens provided per timespan.temporalFactor
- Temporal multiplier corresponding to token time tracking.spreadFactor
- Factor corresponding to token supply spread (from multiple indices).totalLimitFactor
- Factor to multiply adjustedTotalLimit by to decrease the chance of hitting the
rate limit.public TokenTemporalBucket(long timespan, int totalLimit, int temporalFactor, float spreadFactor, float totalLimitFactor, Supplier<Long> timeSupplier)
timespan
- The time per bucket in milliseconds.totalLimit
- The maximum number of tokens provided per timespan.temporalFactor
- Temporal multiplier corresponding to token time tracking.spreadFactor
- Factor corresponding to token supply spread (from multiple indices).totalLimitFactor
- Factor to multiply adjustedTotalLimit by to decrease the chance of hitting the
rate limit.timeSupplier
- Supplies non-descending millisecond time, useful for debugging.public long getDelay()
TemporalBucket
getDelay
in class TemporalBucket
public boolean getTokens(int n)
TemporalBucket
getTokens
in class TemporalBucket
public long getTimespan()
TemporalBucket
getTimespan
in class TemporalBucket
public int getTotalLimit()
TemporalBucket
getTotalLimit
in class TemporalBucket
public final int hashCode()
Copyright © 2019. All rights reserved.