Class RateLimiterExecutor
- java.lang.Object
-
- org.threadly.concurrent.wrapper.limiter.RateLimiterExecutor
-
- All Implemented Interfaces:
java.util.concurrent.Executor
,SubmitterExecutor
public class RateLimiterExecutor extends java.lang.Object implements SubmitterExecutor
Another way to limit executions on a scheduler. Unlike theExecutorLimiter
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.
- Since:
- 4.6.0 (since 2.0.0 at org.threadly.concurrent.limiter)
-
-
Constructor Summary
Constructors Constructor Description RateLimiterExecutor(SubmitterScheduler scheduler, double permitsPerSecond)
Constructs a newRateLimiterExecutor
.RateLimiterExecutor(SubmitterScheduler scheduler, double permitsPerSecond, long maxScheduleDelayMillis)
Constructs a newRateLimiterExecutor
.RateLimiterExecutor(SubmitterScheduler scheduler, double permitsPerSecond, long maxScheduleDelayMillis, RejectedExecutionHandler rejectedExecutionHandler)
Constructs a newRateLimiterExecutor
.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method 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.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(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).<T> ListenableFuture<T>
submit(java.lang.Runnable task, T result)
Submit a task to run as soon as possible.<T> ListenableFuture<T>
submit(java.util.concurrent.Callable<T> task)
Submit aCallable
to run as soon as possible.-
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface org.threadly.concurrent.SubmitterExecutor
submit
-
-
-
-
Constructor Detail
-
RateLimiterExecutor
public RateLimiterExecutor(SubmitterScheduler scheduler, double permitsPerSecond)
Constructs a newRateLimiterExecutor
. 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)
.- Parameters:
scheduler
- scheduler to schedule/execute tasks onpermitsPerSecond
- how many permits should be allowed per second
-
RateLimiterExecutor
public RateLimiterExecutor(SubmitterScheduler scheduler, double permitsPerSecond, long maxScheduleDelayMillis)
Constructs a newRateLimiterExecutor
. 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.- Parameters:
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 rate- Since:
- 4.8.0
-
RateLimiterExecutor
public RateLimiterExecutor(SubmitterScheduler scheduler, double permitsPerSecond, long maxScheduleDelayMillis, RejectedExecutionHandler rejectedExecutionHandler)
Constructs a newRateLimiterExecutor
. 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.- Parameters:
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 executed- Since:
- 4.8.0
-
-
Method Detail
-
setPermitsPerSecond
public void setPermitsPerSecond(double permitsPerSecond)
Sets the allowed permits per second. When this rate is updated, it only applies to future submitted task. In addition if the rate has already been exceeded (and thus there is a delay in scheduling future items), that delay based off the previous permit rate will not be adjusted. For example if the rate was1/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.- Parameters:
permitsPerSecond
- how many permits should be allowed per second- Since:
- 4.6.3
-
setMaxScheduleDelayMillis
public 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. This value must be greater than zero.- Parameters:
maxScheduleDelayMillis
- Maximum task delay in milliseconds- Since:
- 4.8.0
-
getMinimumDelay
public int getMinimumDelay()
This call will check how far out we have already scheduled tasks to be run. Because it is the applications responsibility to not provide tasks too fast for the limiter to run them, this can give an idea of how backed up tasks provided through this limiter actually are.- Returns:
- minimum delay in milliseconds for the next task to be provided
-
getFutureTillDelay
public 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. If you want to ensure that the next task will execute immediately, you should provide a zero to this function. If more tasks are added to the limiter after this call, it will NOT impact when this future will unblock. So this future is assuming that nothing else is added to the limiter after requested.- Parameters:
maximumDelay
- maximum delay in milliseconds until returned Future should unblock- Returns:
- Future that will unblock
get()
calls once delay has been reduced below the provided maximum
-
execute
public void execute(java.lang.Runnable task)
- Specified by:
execute
in interfacejava.util.concurrent.Executor
-
execute
public 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). The task will be scheduled out as far as necessary to ensure it conforms to the set rate.- Parameters:
permits
- resource permits for this tasktask
- Runnable to execute when ready- Returns:
- Time in milliseconds task was delayed to maintain rate, or
-1
if rejected but handler did not throw
-
submit
public <T> ListenableFuture<T> submit(java.lang.Runnable task, T result)
Description copied from interface:SubmitterExecutor
Submit a task to run as soon as possible. TheFuture.get()
method will return the provided result once the runnable has completed.- Specified by:
submit
in interfaceSubmitterExecutor
- Type Parameters:
T
- type of result for future- Parameters:
task
- runnable to be executedresult
- result to be returned from resulting future .get() when runnable completes- Returns:
- a future to know when the task has completed
-
submit
public 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). The task will be scheduled out as far as necessary to ensure it conforms to the set rate.- Parameters:
permits
- resource permits for this tasktask
- Runnable to execute when ready- Returns:
- Future that will indicate when the execution of this task has completed
-
submit
public <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). The task will be scheduled out as far as necessary to ensure it conforms to the set rate.- Type Parameters:
T
- type of result returned from the future- Parameters:
permits
- resource permits for this tasktask
- Runnable to execute when readyresult
- result to return from future when task completes- Returns:
- Future that will return provided result when the execution has completed
-
submit
public <T> ListenableFuture<T> submit(java.util.concurrent.Callable<T> task)
Description copied from interface:SubmitterExecutor
Submit aCallable
to run as soon as possible. This is needed when a result needs to be consumed from the callable.- Specified by:
submit
in interfaceSubmitterExecutor
- Type Parameters:
T
- type of result returned from the future- Parameters:
task
- callable to be executed- Returns:
- a future to know when the task has completed and get the result of the callable
-
submit
public <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). The task will be scheduled out as far as necessary to ensure it conforms to the set rate.- Type Parameters:
T
- type of result returned from the future- Parameters:
permits
- resource permits for this tasktask
- Callable to execute when ready- Returns:
- Future that will return the callables provided result when the execution has completed
-
-