Guava’s RateLimiter per minutes instead of seconds?

前端 未结 6 2353
情话喂你
情话喂你 2021-02-13 21:28

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

6条回答
  •  一整个雨季
    2021-02-13 21:56

    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.

提交回复
热议问题