Skip to content

Java Rate Limiter Derived From Googles' Guava Implementation

License

Notifications You must be signed in to change notification settings

comodal/throttle

Repository files navigation

Throttle Build Status Download License

Provides a mechanism to limit the rate of access to a resource.

Usage

A Throttle instance distributes permits at a desired rate, blocking if necessary until a permit is available.

Submit two tasks per second:
Throttle throttle = Throttle.create(2.0); // 2 permits per second
// ...
void submitTasksBlocking(List<Runnable> tasks, Executor executor) {
  for (var task : tasks) {
    throttle.acquireUnchecked();
    executor.execute(task);
  }
}

void submitTasksNonBlocking(List<Runnable> tasks, Executor executor) {
  for (var task : tasks) {
    long delay = throttle.acquireDelayDuration();
    if (delay > 0) {
      CompletableFuture.runAsync(task,
        CompletableFuture.delayedExecutor(delay, NANOSECONDS, executor));
      continue;
    }
    CompletableFuture.runAsync(task, executor);
  }
}
Cap data stream to 5kb per second:
Throttle throttle = Throttle.create(5000.0); // 5000 permits per second
// ...
void submitPacket(byte[] packet) {
  throttle.acquire(packet.length);
  networkService.send(packet);
}

Changes From Guava Rate Limiter

  • Nanosecond instead of microsecond accuracy.
  • Uses a ReentrantLock instead of synchronized blocks to support optional fair acquisition ordering.
  • Factoring out an interface class, Throttle, from the base abstract class.
  • Remove the need for any non-core-Java classes outside of the original RateLimiter and SmoothRateLimiter classes.
  • Remove the need for a SleepingStopwatch or similar class instance.
  • Guava provides rate limiters with either bursty or warm-up behavior. Throttle provides only a single strict rate limiter implementation that will never exceed the desired rate limit over a one second period.
  • Throws checked InterruptedException's or unchecked CompletionException's with the cause set to the corresponding InterruptedException if interrupted.