Class SmoothRateLimiter.SmoothWarmingUp
java.lang.Object
com.google.common.util.concurrent.RateLimiter
com.google.common.util.concurrent.SmoothRateLimiter
com.google.common.util.concurrent.SmoothRateLimiter.SmoothWarmingUp
- Enclosing class:
SmoothRateLimiter
This implements the following function where coldInterval = coldFactor * stableInterval.
^ throttling | cold + / interval | /. | / . | / . ← "warmup period" is the area of the trapezoid between | / . thresholdPermits and maxPermits | / . | / . | / . stable +----------/ WARM . interval | . UP . | . PERIOD. | . . 0 +----------+-------+--------------→ storedPermits 0 thresholdPermits maxPermitsBefore going into the details of this particular function, let's keep in mind the basics:
- The state of the RateLimiter (storedPermits) is a vertical line in this figure.
- When the RateLimiter is not used, this goes right (up to maxPermits)
- When the RateLimiter is used, this goes left (down to zero), since if we have storedPermits, we serve from those first
- When _unused_, we go right at a constant rate! The rate at which we move to the right is chosen as maxPermits / warmupPeriod. This ensures that the time it takes to go from 0 to maxPermits is equal to warmupPeriod.
- When _used_, the time it takes, as explained in the introductory class note, is equal to the integral of our function, between X permits and X-K permits, assuming we want to spend K saved permits.
In summary, the time it takes to move to the left (spend K permits), is equal to the area of the function of width == K.
Assuming we have saturated demand, the time to go from maxPermits to thresholdPermits is equal to warmupPeriod. And the time to go from thresholdPermits to 0 is warmupPeriod/2. (The reason that this is warmupPeriod/2 is to maintain the behavior of the original implementation where coldFactor was hard coded as 3.)
It remains to calculate thresholdsPermits and maxPermits.
- The time to go from thresholdPermits to 0 is equal to the integral of the function
between 0 and thresholdPermits. This is thresholdPermits * stableIntervals. By (5) it is
also equal to warmupPeriod/2. Therefore
thresholdPermits = 0.5 * warmupPeriod / stableInterval
- The time to go from maxPermits to thresholdPermits is equal to the integral of the
function between thresholdPermits and maxPermits. This is the area of the pictured
trapezoid, and it is equal to 0.5 * (stableInterval + coldInterval) * (maxPermits -
thresholdPermits). It is also equal to warmupPeriod, so
maxPermits = thresholdPermits + 2 * warmupPeriod / (stableInterval + coldInterval)
-
Nested Class Summary
Nested classes/interfaces inherited from class com.google.common.util.concurrent.SmoothRateLimiter
SmoothRateLimiter.SmoothBursty, SmoothRateLimiter.SmoothWarmingUp
Nested classes/interfaces inherited from class com.google.common.util.concurrent.RateLimiter
RateLimiter.SleepingStopwatch
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate double
private double
The slope of the line from the stable interval (when permits == 0), to the cold interval (when permits == maxPermits)private double
private final long
Fields inherited from class com.google.common.util.concurrent.SmoothRateLimiter
maxPermits, stableIntervalMicros, storedPermits
-
Constructor Summary
ConstructorsConstructorDescriptionSmoothWarmingUp
(RateLimiter.SleepingStopwatch stopwatch, long warmupPeriod, TimeUnit timeUnit, double coldFactor) -
Method Summary
Modifier and TypeMethodDescription(package private) double
Returns the number of microseconds during cool down that we have to wait to get a new permit.(package private) void
doSetRate
(double permitsPerSecond, double stableIntervalMicros) private double
permitsToTime
(double permits) (package private) long
storedPermitsToWaitTime
(double storedPermits, double permitsToTake) Translates a specified portion of our currently stored permits which we want to spend/acquire, into a throttling time.Methods inherited from class com.google.common.util.concurrent.SmoothRateLimiter
doGetRate, doSetRate, queryEarliestAvailable, reserveEarliestAvailable, resync
Methods inherited from class com.google.common.util.concurrent.RateLimiter
acquire, acquire, create, create, create, create, create, getRate, reserve, reserveAndGetWaitLength, setRate, toString, tryAcquire, tryAcquire, tryAcquire, tryAcquire, tryAcquire, tryAcquire
-
Field Details
-
warmupPeriodMicros
private final long warmupPeriodMicros -
slope
private double slopeThe slope of the line from the stable interval (when permits == 0), to the cold interval (when permits == maxPermits) -
thresholdPermits
private double thresholdPermits -
coldFactor
private double coldFactor
-
-
Constructor Details
-
SmoothWarmingUp
SmoothWarmingUp(RateLimiter.SleepingStopwatch stopwatch, long warmupPeriod, TimeUnit timeUnit, double coldFactor)
-
-
Method Details
-
doSetRate
void doSetRate(double permitsPerSecond, double stableIntervalMicros) - Specified by:
doSetRate
in classSmoothRateLimiter
-
storedPermitsToWaitTime
long storedPermitsToWaitTime(double storedPermits, double permitsToTake) Description copied from class:SmoothRateLimiter
Translates a specified portion of our currently stored permits which we want to spend/acquire, into a throttling time. Conceptually, this evaluates the integral of the underlying function we use, for the range of [(storedPermits - permitsToTake), storedPermits].This always holds:
0 <= permitsToTake <= storedPermits
- Specified by:
storedPermitsToWaitTime
in classSmoothRateLimiter
-
permitsToTime
private double permitsToTime(double permits) -
coolDownIntervalMicros
double coolDownIntervalMicros()Description copied from class:SmoothRateLimiter
Returns the number of microseconds during cool down that we have to wait to get a new permit.- Specified by:
coolDownIntervalMicros
in classSmoothRateLimiter
-