public class RateLimiterExecutor extends java.lang.Object implements SubmitterExecutor
ExecutorLimiter
this does
not attempt to limit concurrency. Instead it schedules tasks on a scheduler so that given
permits are only used at a rate per second. This can be used for limiting the rate of data
that you want to put on hardware resource (in a non-blocking way).
It is important to note that if something is executed and it exceeds the rate, it will be future tasks which are delayed longer.
It is also important to note that it is the responsibility of the application to not be providing more tasks into this limiter than can be consumed at the rate. Since this limiter will not block, if provided tasks too fast they could continue to be scheduled out further and further. This should be used to flatten out possible bursts that could be used in the application, it is not designed to be a push back mechanism for the application.
Constructor and Description |
---|
RateLimiterExecutor(SubmitterScheduler scheduler,
double permitsPerSecond)
Constructs a new
RateLimiterExecutor . |
RateLimiterExecutor(SubmitterScheduler scheduler,
double permitsPerSecond,
long maxScheduleDelayMillis)
Constructs a new
RateLimiterExecutor . |
RateLimiterExecutor(SubmitterScheduler scheduler,
double permitsPerSecond,
long maxScheduleDelayMillis,
RejectedExecutionHandler rejectedExecutionHandler)
Constructs a new
RateLimiterExecutor . |
Modifier and Type | Method and Description |
---|---|
long |
execute(double permits,
java.lang.Runnable task)
Exact same as execute counter part, except you can specify how many permits this task will
require/use (instead of defaulting to 1).
|
void |
execute(java.lang.Runnable task) |
ListenableFuture<?> |
getFutureTillDelay(long maximumDelay)
In order to help assist with avoiding to schedule too much on the scheduler at any given
time, this call returns a future that will block until the delay for the next task falls
below the maximum delay provided into this call.
|
int |
getMinimumDelay()
This call will check how far out we have already scheduled tasks to be run.
|
void |
setMaxScheduleDelayMillis(long maxScheduleDelayMillis)
At runtime adjust the maximum amount that this rate limiter will be willing to schedule out
tasks in order to maintain the rate.
|
void |
setPermitsPerSecond(double permitsPerSecond)
Sets the allowed permits per second.
|
<T> ListenableFuture<T> |
submit(java.util.concurrent.Callable<T> task)
Submit a
Callable to run as soon as possible. |
<T> ListenableFuture<T> |
submit(double permits,
java.util.concurrent.Callable<T> task)
Exact same as the submit counter part, except you can specify how many permits this task will
require/use (instead of defaulting to 1).
|
ListenableFuture<?> |
submit(double permits,
java.lang.Runnable task)
Exact same as the submit counter part, except you can specify how many permits this task will
require/use (instead of defaulting to 1).
|
<T> ListenableFuture<T> |
submit(double permits,
java.lang.Runnable task,
T result)
Exact same as the submit counter part, except you can specify how many permits this task will
require/use (instead of defaulting to 1).
|
<T> ListenableFuture<T> |
submit(java.lang.Runnable task,
T result)
Submit a task to run as soon as possible.
|
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
submit
public RateLimiterExecutor(SubmitterScheduler scheduler, double permitsPerSecond)
RateLimiterExecutor
. Tasks will be scheduled on the provided
scheduler, so it is assumed that the scheduler will have enough threads to handle the
average permit amount per task, per second.
This will schedule tasks out infinitely far in order to maintain rate. If you want tasks to
be rejected at a certain point consider using
RateLimiterExecutor(SubmitterScheduler, double, long)
.
scheduler
- scheduler to schedule/execute tasks onpermitsPerSecond
- how many permits should be allowed per secondpublic RateLimiterExecutor(SubmitterScheduler scheduler, double permitsPerSecond, long maxScheduleDelayMillis)
RateLimiterExecutor
. Tasks will be scheduled on the provided
scheduler, so it is assumed that the scheduler will have enough threads to handle the
average permit amount per task, per second.
This constructor accepts a maximum schedule delay. If a task requires being scheduled out
beyond this delay, then a RejectedExecutionException
will be
thrown instead of scheduling the task.
scheduler
- scheduler to schedule/execute tasks onpermitsPerSecond
- how many permits should be allowed per secondmaxScheduleDelayMillis
- Maximum amount of time delay tasks in order to maintain ratepublic RateLimiterExecutor(SubmitterScheduler scheduler, double permitsPerSecond, long maxScheduleDelayMillis, RejectedExecutionHandler rejectedExecutionHandler)
RateLimiterExecutor
. Tasks will be scheduled on the provided
scheduler, so it is assumed that the scheduler will have enough threads to handle the
average permit amount per task, per second.
This constructor accepts a maximum schedule delay. If a task requires being scheduled out
beyond this delay, then the provided RejectedExecutionHandler
will be invoked.
scheduler
- scheduler to schedule/execute tasks onpermitsPerSecond
- how many permits should be allowed per secondmaxScheduleDelayMillis
- Maximum amount of time delay tasks in order to maintain raterejectedExecutionHandler
- Handler to accept tasks which could not be executedpublic void setPermitsPerSecond(double permitsPerSecond)
1/sec
and a 10 permit task was just submitted,
and thus we have a delay of 10 seconds for a future task. Adjusting this higher will NOT
reduce the delay time for the next task, it will only effect schedule rates after currently
scheduled tasks have been satisfied.permitsPerSecond
- how many permits should be allowed per secondpublic void setMaxScheduleDelayMillis(long maxScheduleDelayMillis)
maxScheduleDelayMillis
- Maximum task delay in millisecondspublic int getMinimumDelay()
public ListenableFuture<?> getFutureTillDelay(long maximumDelay)
maximumDelay
- maximum delay in milliseconds until returned Future should unblockget()
calls once delay has been reduced below the provided maximumpublic void execute(java.lang.Runnable task)
execute
in interface java.util.concurrent.Executor
public long execute(double permits, java.lang.Runnable task)
permits
- resource permits for this tasktask
- Runnable to execute when ready-1
if rejected but handler did not throwpublic <T> ListenableFuture<T> submit(java.lang.Runnable task, T result)
SubmitterExecutor
Future.get()
method will
return the provided result once the runnable has completed.submit
in interface SubmitterExecutor
T
- type of result for futuretask
- runnable to be executedresult
- result to be returned from resulting future .get() when runnable completespublic ListenableFuture<?> submit(double permits, java.lang.Runnable task)
permits
- resource permits for this tasktask
- Runnable to execute when readypublic <T> ListenableFuture<T> submit(double permits, java.lang.Runnable task, T result)
T
- type of result returned from the futurepermits
- resource permits for this tasktask
- Runnable to execute when readyresult
- result to return from future when task completespublic <T> ListenableFuture<T> submit(java.util.concurrent.Callable<T> task)
SubmitterExecutor
Callable
to run as soon as possible. This is needed when a result needs to
be consumed from the callable.submit
in interface SubmitterExecutor
T
- type of result returned from the futuretask
- callable to be executedpublic <T> ListenableFuture<T> submit(double permits, java.util.concurrent.Callable<T> task)
T
- type of result returned from the futurepermits
- resource permits for this tasktask
- Callable to execute when ready