Problem:
I have a client app in Java that needs to adhere to multiple rate limits. For example, req/second, req/minute, req/hour…etc. The app will only permit a call if the app is within all of the limits.
When I implement the rate limiters using either Resilence4J or Google Guava, it ends up consuming permits for all rate limits that returned true
, even though at least one of the rate limits returned false
.
Example (assuming Guava):
If I have an REQ_PER_SECOND
RateLimit
and a REQ_PER_MINUTE
RateLimit
defined, it’s possible that REQ_PER_SECOND.tryAcquire()
returns true
, but REQ_PER_MINUTE.tryAcquire()
returns false
.
In this case, an API call will not be made, but it still ended up consuming permits for REQ_PER_SECOND
.
This results in the app throttling itself all the time.
Note: we can’t just throw this problem to the server due to cost and performance reasons.
Question
Is there a way to do this with Guava or Resilience4J libraries? If not, what’s the best way to handle this problem?
Guava has a setRate(int rate)
method, but I think that only sets the stable rate, but does not actually reset the rates already consumed. So that wouldn’t work.
Any suggestion is greatly appreciated!