Class KeyedRateLimiterExecutor


  • public class KeyedRateLimiterExecutor
    extends java.lang.Object
    Similar to RateLimiterExecutor except that the rate is applied on a per key basis. Tasks submitted to this executor must all be associated to a key. The key is compared by using Object.hashCode() and Object.equals(Object). For any given key, a rate is applied, but keys which don't match with the above checks will not impact each other.

    Because different keys don't interact, this is not capable of providing a global rate limit (unless the key quantity is known and restricted).

    This differs from KeyedExecutorLimiter in that while that limits concurrency, this limits by rate (thus there may be periods where nothing is execution, or if executions are long things may run concurrently). Please see RateLimiterExecutor for more details about how rate is limited.

    Since:
    4.7.0
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      long execute​(double permits, java.lang.Object taskKey, java.lang.Runnable task)
      Provide a task to be run with a given thread key.
      void execute​(java.lang.Object taskKey, java.lang.Runnable task)
      Provide a task to be run with a given thread key.
      ListenableFuture<?> getFutureTillDelay​(java.lang.Object taskKey, 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​(java.lang.Object taskKey)
      This call will check how far out we have already scheduled tasks to be run.
      SubmitterExecutor getSubmitterExecutorForKey​(double permits, java.lang.Object taskKey)
      Returns an executor implementation where all tasks submitted on this executor will run on the provided key.
      SubmitterExecutor getSubmitterExecutorForKey​(java.lang.Object taskKey)
      Returns an executor implementation where all tasks submitted on this executor will run on the provided key.
      int getTrackedKeyCount()
      Check how many keys are currently being restricted or monitored.
      ListenableFuture<?> submit​(double permits, java.lang.Object taskKey, java.lang.Runnable task)
      Submit a task to be run with a given thread key.
      <T> ListenableFuture<T> submit​(double permits, java.lang.Object taskKey, java.lang.Runnable task, T result)
      Submit a task to be run with a given thread key.
      <T> ListenableFuture<T> submit​(double permits, java.lang.Object taskKey, java.util.concurrent.Callable<T> task)
      Submit a callable to be run with a given thread key.
      ListenableFuture<?> submit​(java.lang.Object taskKey, java.lang.Runnable task)
      Submit a task to be run with a given thread key.
      <T> ListenableFuture<T> submit​(java.lang.Object taskKey, java.lang.Runnable task, T result)
      Submit a task to be run with a given thread key.
      <T> ListenableFuture<T> submit​(java.lang.Object taskKey, java.util.concurrent.Callable<T> task)
      Submit a callable to be run with a given thread key.
      • Methods inherited from class java.lang.Object

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

      • KeyedRateLimiterExecutor

        public KeyedRateLimiterExecutor​(SubmitterScheduler scheduler,
                                        double permitsPerSecond)
        Constructs a new key rate limiting executor. Using sensible default options.

        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 KeyedRateLimiterExecutor(SubmitterScheduler, double, long).

        Parameters:
        scheduler - Scheduler to defer executions to
        permitsPerSecond - how many permits should be allowed per second per key
      • KeyedRateLimiterExecutor

        public KeyedRateLimiterExecutor​(SubmitterScheduler scheduler,
                                        double permitsPerSecond,
                                        java.lang.String subPoolName,
                                        boolean addKeyToThreadName)
        Constructs a new key rate limiting executor. Allowing the specification of thread naming behavior. Providing null or empty for the subPoolName and false for appending the key to the thread name will result in no thread name adjustments occurring.

        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 KeyedRateLimiterExecutor(SubmitterScheduler, double, long, String, boolean).

        Parameters:
        scheduler - Scheduler to defer executions to
        permitsPerSecond - how many permits should be allowed per second per key
        subPoolName - Prefix to give threads while executing tasks submitted through this limiter
        addKeyToThreadName - true to append the task's key to the thread name
      • KeyedRateLimiterExecutor

        public KeyedRateLimiterExecutor​(SubmitterScheduler scheduler,
                                        double permitsPerSecond,
                                        long maxScheduleDelayMillis)
        Constructs a new key rate limiting executor.

        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 defer executions to
        permitsPerSecond - how many permits should be allowed per second per key
        maxScheduleDelayMillis - Maximum amount of time delay tasks in order to maintain rate
        Since:
        4.8.0
      • KeyedRateLimiterExecutor

        public KeyedRateLimiterExecutor​(SubmitterScheduler scheduler,
                                        double permitsPerSecond,
                                        long maxScheduleDelayMillis,
                                        RejectedExecutionHandler rejectedExecutionHandler)
        Constructs a new key rate limiting executor.

        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 defer executions to
        permitsPerSecond - how many permits should be allowed per second per key
        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
      • KeyedRateLimiterExecutor

        public KeyedRateLimiterExecutor​(SubmitterScheduler scheduler,
                                        double permitsPerSecond,
                                        long maxScheduleDelayMillis,
                                        java.lang.String subPoolName,
                                        boolean addKeyToThreadName)
        Constructs a new key rate limiting executor. Allowing the specification of thread naming behavior. Providing null or empty for the subPoolName and false for appending the key to the thread name will result in no thread name adjustments occurring.

        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 defer executions to
        permitsPerSecond - how many permits should be allowed per second per key
        maxScheduleDelayMillis - Maximum amount of time delay tasks in order to maintain rate
        subPoolName - Prefix to give threads while executing tasks submitted through this limiter
        addKeyToThreadName - true to append the task's key to the thread name
        Since:
        4.8.0
      • KeyedRateLimiterExecutor

        public KeyedRateLimiterExecutor​(SubmitterScheduler scheduler,
                                        double permitsPerSecond,
                                        long maxScheduleDelayMillis,
                                        RejectedExecutionHandler rejectedExecutionHandler,
                                        java.lang.String subPoolName,
                                        boolean addKeyToThreadName)
        Constructs a new key rate limiting executor. Allowing the specification of thread naming behavior. Providing null or empty for the subPoolName and false for appending the key to the thread name will result in no thread name adjustments occurring.

        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 defer executions to
        permitsPerSecond - how many permits should be allowed per second per key
        maxScheduleDelayMillis - Maximum amount of time delay tasks in order to maintain rate
        rejectedExecutionHandler - Handler to accept tasks which could not be executed
        subPoolName - Prefix to give threads while executing tasks submitted through this limiter
        addKeyToThreadName - true to append the task's key to the thread name
        Since:
        4.8.0
    • Method Detail

      • getTrackedKeyCount

        public int getTrackedKeyCount()
        Check how many keys are currently being restricted or monitored. This number is particularly relevant for when checking the queued tasks of the parent scheduler. As part of the inner workings of this limiter, a task will exist for each key. Because of that there will be queued tasks which are not actual application submitted work units.
        Returns:
        The number of task keys being monitored
      • getMinimumDelay

        public int getMinimumDelay​(java.lang.Object taskKey)
        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.
        Parameters:
        taskKey - object key where equals() will be used to determine execution thread
        Returns:
        minimum delay in milliseconds for the next task to be provided
      • getFutureTillDelay

        public ListenableFuture<?> getFutureTillDelay​(java.lang.Object taskKey,
                                                      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:
        taskKey - object key where equals() will be used to determine execution thread
        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.Object taskKey,
                            java.lang.Runnable task)
        Provide a task to be run with a given thread key.

        See also: Executor.execute(Runnable) and RateLimiterExecutor.execute(Runnable).

        Parameters:
        taskKey - object key where equals() will be used to determine execution thread
        task - Task to be executed
      • execute

        public long execute​(double permits,
                            java.lang.Object taskKey,
                            java.lang.Runnable task)
        Provide a task to be run with a given thread key.

        See also: Executor.execute(Runnable) and RateLimiterExecutor.execute(double, Runnable).

        Parameters:
        permits - resource permits for this task
        taskKey - object key where equals() will be used to determine execution thread
        task - Task to be executed
        Returns:
        Time in milliseconds task was delayed to maintain rate, or -1 if rejected but handler did not throw
      • submit

        public ListenableFuture<?> submit​(double permits,
                                          java.lang.Object taskKey,
                                          java.lang.Runnable task)
        Submit a task to be run with a given thread key.

        See also: SubmitterExecutor.submit(Runnable) and RateLimiterExecutor.submit(double, Runnable).

        Parameters:
        permits - resource permits for this task
        taskKey - object key where equals() will be used to determine execution thread
        task - Task to be executed
        Returns:
        Future to represent when the execution has occurred
      • submit

        public <T> ListenableFuture<T> submit​(java.lang.Object taskKey,
                                              java.lang.Runnable task,
                                              T result)
        Submit a task to be run with a given thread key.

        See also: SubmitterExecutor.submit(Runnable, Object) and RateLimiterExecutor.submit(Runnable, Object).

        Type Parameters:
        T - type of result returned from the future
        Parameters:
        taskKey - object key where equals() will be used to determine execution thread
        task - Runnable to be executed
        result - Result to be returned from future when task completes
        Returns:
        Future to represent when the execution has occurred and provide the given result
      • submit

        public <T> ListenableFuture<T> submit​(double permits,
                                              java.lang.Object taskKey,
                                              java.lang.Runnable task,
                                              T result)
        Submit a task to be run with a given thread key.

        See also: SubmitterExecutor.submit(Runnable, Object) and RateLimiterExecutor.submit(double, Runnable, Object).

        Type Parameters:
        T - type of result returned from the future
        Parameters:
        permits - resource permits for this task
        taskKey - object key where equals() will be used to determine execution thread
        task - Runnable to be executed
        result - Result to be returned from future when task completes
        Returns:
        Future to represent when the execution has occurred and provide the given result
      • submit

        public <T> ListenableFuture<T> submit​(java.lang.Object taskKey,
                                              java.util.concurrent.Callable<T> task)
        Submit a callable to be run with a given thread key.

        See also: SubmitterExecutor.submit(Callable) and RateLimiterExecutor.submit(Callable).

        Type Parameters:
        T - type of result returned from the future
        Parameters:
        taskKey - object key where equals() will be used to determine execution thread
        task - Callable to be executed
        Returns:
        Future to represent when the execution has occurred and provide the result from the callable
      • submit

        public <T> ListenableFuture<T> submit​(double permits,
                                              java.lang.Object taskKey,
                                              java.util.concurrent.Callable<T> task)
        Submit a callable to be run with a given thread key.

        See also: SubmitterExecutor.submit(Callable) and RateLimiterExecutor.submit(double, Callable).

        Type Parameters:
        T - type of result returned from the future
        Parameters:
        permits - resource permits for this task
        taskKey - object key where equals() will be used to determine execution thread
        task - Callable to be executed
        Returns:
        Future to represent when the execution has occurred and provide the result from the callable
      • getSubmitterExecutorForKey

        public SubmitterExecutor getSubmitterExecutorForKey​(java.lang.Object taskKey)
        Returns an executor implementation where all tasks submitted on this executor will run on the provided key. Tasks executed on the returned scheduler will be limited by the key submitted on this instance equally with ones provided through the returned instance.
        Parameters:
        taskKey - object key where equals() will be used to determine execution thread
        Returns:
        Executor which will only execute with reference to the provided key
      • getSubmitterExecutorForKey

        public SubmitterExecutor getSubmitterExecutorForKey​(double permits,
                                                            java.lang.Object taskKey)
        Returns an executor implementation where all tasks submitted on this executor will run on the provided key. Tasks executed on the returned scheduler will be limited by the key submitted on this instance equally with ones provided through the returned instance.
        Parameters:
        permits - resource permits for all tasks submitted on the returned executor
        taskKey - object key where equals() will be used to determine execution thread
        Returns:
        Executor which will only execute with reference to the provided key