public class AverageRateLimiter extends Object implements Startable, RateLimiter
This rate limiter uses nanoseconds as the unit of timing. This
works well because it is the native precision of the system timer
interface via System.nanoTime(). It is also low-error
in terms of rounding between floating point rates and nanoseconds,
at least in the round numbers that users tend to use. Further,
the current scheduling state is maintained as an atomic view of
accumulated nanoseconds granted to callers -- referred to here as the
ticks accumulator. This further simplifies the implementation by
allowing direct comparison of scheduled times with the current
state of the high-resolution system timer.
Each time acquire() or acquire(long) is called,
a discrete scheduled time is calculated from the current state of
the ticks accumulator. If the calculated time is in the future,
then the method blocks (in the calling thread) using
Thread.sleep(long, int). Finally, the method is unblocked,
and the nanosecond scheduling gap is returned to the caller.
This implementation of the rate limiter is simplified to only support
averaging rate limits. The RateLimiters class provides a
convenient way for using either the averaging rate limiter or the
strict rate limiter at runtime, while allowing the averaging rate
limiter to be used when desired for higher client-side throughput.
Note that the ticks accumulator can not rate limit a single event. Acquiring a grant at some nanosecond size simply consumes nanoseconds from the schedule, with the start time of the allotted time span being conceptually aligned with the start time of the requested event. In other words, previous allocations of the timeline determine the start time of a subsequent caller, not the caller itself.
| Modifier and Type | Field and Description |
|---|---|
protected AtomicLong |
ticksTimeline |
| Modifier | Constructor and Description |
|---|---|
protected |
AverageRateLimiter() |
|
AverageRateLimiter(ActivityDef def,
String label,
RateSpec rateSpec)
Create a rate limiter.
|
| Modifier and Type | Method and Description |
|---|---|
long |
acquire()
Block until it is time for the next operation, according to the
nanoseconds per op as set by
RateLimiter.setRate(double) |
long |
acquire(long nanos)
See
AverageRateLimiter for interface docs. |
long |
getLastSeenNanoTimeline()
visible for testing
|
protected long |
getNanoClockTime() |
long |
getOpNanos()
Get the number of nanoseconds allotted to each operations.
|
double |
getRate()
Return the rate in ops/s.
|
protected long |
getRateSchedulingDelay() |
RateSpec |
getRateSpec()
Get the rate spec that this rate limiter was created from.
|
AtomicLong |
getTicksTimeline()
* visible for testing
|
long |
getTotalSchedulingDelay()
Return the total number of nanoseconds behind schedule
that this rate limiter is, including the full history across all
rates.
|
protected void |
init() |
protected void |
setActivityDef(ActivityDef def) |
protected void |
setLabel(String label) |
void |
setRate(double rate)
Set the rate in ops/s.
|
void |
setRateSpec(RateSpec updatingRateSpec)
Modify the rate of a running rate limiter.
|
void |
start() |
String |
toString() |
protected final AtomicLong ticksTimeline
protected AverageRateLimiter()
public AverageRateLimiter(ActivityDef def, String label, RateSpec rateSpec)
def - The activity definition for this rate limiterlabel - The label for the rate limiting facet within the activityrateSpec - the rate limiter configurationprotected void setLabel(String label)
protected void setActivityDef(ActivityDef def)
protected void init()
protected long getNanoClockTime()
public long acquire(long nanos)
AverageRateLimiter for interface docs.
effective calling overhead of acquire() is ~20nsacquire in interface RateLimiternanos - nanoseconds of time allotted to this eventpublic long acquire()
RateLimiterRateLimiter.setRate(double)acquire in interface RateLimiterpublic long getOpNanos()
RateLimitergetOpNanos in interface RateLimiterpublic double getRate()
RateLimitergetRate in interface RateLimiterpublic void setRate(double rate)
RateLimitersetRate in interface RateLimiterrate - The desired ops/s rate.public long getTotalSchedulingDelay()
RateLimitergetTotalSchedulingDelay in interface RateLimiterprotected long getRateSchedulingDelay()
public RateSpec getRateSpec()
RateLimitergetRateSpec in interface RateLimiterpublic void setRateSpec(RateSpec updatingRateSpec)
RateLimitersetRateSpec in interface RateLimiterupdatingRateSpec - The rate and burstRatio specificationpublic AtomicLong getTicksTimeline()
public long getLastSeenNanoTimeline()
Copyright © 2018. All rights reserved.