Throttling method calls to M requests in N seconds
Solution 1:
I'd use a ring buffer of timestamps with a fixed size of M. Each time the method is called, you check the oldest entry, and if it's less than N seconds in the past, you execute and add another entry, otherwise you sleep for the time difference.
Solution 2:
What worked out of the box for me was Google Guava RateLimiter.
// Allow one request per second
private RateLimiter throttle = RateLimiter.create(1.0);
private void someMethod() {
throttle.acquire();
// Do something
}
Solution 3:
In concrete terms, you should be able to implement this with a DelayQueue
. Initialize the queue with M
Delayed
instances with their delay initially set to zero. As requests to the method come in, take
a token, which causes the method to block until the throttling requirement has been met. When a token has been taken, add
a new token to the queue with a delay of N
.