I\'m trying to rate-limit the the number of accounts a user can create with my REST API.
I would have liked to use Guava\'s RateLimiter
to only allow an IP
There's a class called SmoothRateLimiter.SmoothBursty
inside Guava library that implements desired behavior but it has package local access, so we can't use it directly.
There's also a Github issue to make access to that class public: https://github.com/google/guava/issues/1974
If you're not willing to wait until they release a new version of RateLimiter then you could use reflection to instantiate SmoothBursty
rate limiter. Something like this should work:
Class> sleepingStopwatchClass = Class.forName("com.google.common.util.concurrent.RateLimiter$SleepingStopwatch");
Method createStopwatchMethod = sleepingStopwatchClass.getDeclaredMethod("createFromSystemTimer");
createStopwatchMethod.setAccessible(true);
Object stopwatch = createStopwatchMethod.invoke(null);
Class> burstyRateLimiterClass = Class.forName("com.google.common.util.concurrent.SmoothRateLimiter$SmoothBursty");
Constructor> burstyRateLimiterConstructor = burstyRateLimiterClass.getDeclaredConstructors()[0];
burstyRateLimiterConstructor.setAccessible(true);
RateLimiter result = (RateLimiter) burstyRateLimiterConstructor.newInstance(stopwatch, maxBurstSeconds);
result.setRate(permitsPerSecond);
return result;
Yes, new version of Guava might brake your code but if you're willing to accept that risk this might be the way to go.