Class 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 the 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.

    Since:
    4.6.0 (since 2.0.0 at org.threadly.concurrent.limiter)
    • 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 a Callable to run as soon as possible.
      • Methods inherited from class java.lang.Object

        equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • RateLimiterExecutor

        public RateLimiterExecutor​(SubmitterScheduler scheduler,
                                   double permitsPerSecond)
        Constructs a new 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).

        Parameters:
        scheduler - scheduler to schedule/execute tasks on
        permitsPerSecond - how many permits should be allowed per second
      • RateLimiterExecutor

        public RateLimiterExecutor​(SubmitterScheduler scheduler,
                                   double permitsPerSecond,
                                   long maxScheduleDelayMillis)
        Constructs a new 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.

        Parameters:
        scheduler - scheduler to schedule/execute tasks on
        permitsPerSecond - how many permits should be allowed per second
        maxScheduleDelayMillis - 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 new 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.

        Parameters:
        scheduler - scheduler to schedule/execute tasks on
        permitsPerSecond - how many permits should be allowed per second
        maxScheduleDelayMillis - Maximum amount of time delay tasks in order to maintain rate
        rejectedExecutionHandler - 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 was 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.
        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 interface java.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 task
        task - 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. The Future.get() method will return the provided result once the runnable has completed.
        Specified by:
        submit in interface SubmitterExecutor
        Type Parameters:
        T - type of result for future
        Parameters:
        task - runnable to be executed
        result - 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 task
        task - 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 task
        task - Runnable to execute when ready
        result - 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 a Callable to run as soon as possible. This is needed when a result needs to be consumed from the callable.
        Specified by:
        submit in interface SubmitterExecutor
        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 task
        task - Callable to execute when ready
        Returns:
        Future that will return the callables provided result when the execution has completed