diff --git a/redisson/src/main/java/org/redisson/RedissonRateLimiter.java b/redisson/src/main/java/org/redisson/RedissonRateLimiter.java index 46111f006..2762b8c2e 100644 --- a/redisson/src/main/java/org/redisson/RedissonRateLimiter.java +++ b/redisson/src/main/java/org/redisson/RedissonRateLimiter.java @@ -205,8 +205,8 @@ public class RedissonRateLimiter extends RedissonObject implements RRateLimiter + "redis.call('decrby', valueName, ARGV[1]); " + "return nil; " + "end;", - Arrays.asList(getName(), getValueName(), getClientValueName()), - value, commandExecutor.getConnectionManager().getId()); + Arrays.asList(getName(), getValueName(), getClientValueName()), + value); } @Override @@ -220,7 +220,7 @@ public class RedissonRateLimiter extends RedissonObject implements RRateLimiter "redis.call('hsetnx', KEYS[1], 'rate', ARGV[1]);" + "redis.call('hsetnx', KEYS[1], 'interval', ARGV[2]);" + "return redis.call('hsetnx', KEYS[1], 'type', ARGV[3]);", - Collections.singletonList(getName()), rate, unit.toMillis(rateInterval), type.ordinal()); + Collections.singletonList(getName()), rate, unit.toMillis(rateInterval), type.ordinal()); } private static final RedisCommand HGETALL = new RedisCommand("HGETALL", new MultiDecoder() { @@ -263,7 +263,25 @@ public class RedissonRateLimiter extends RedissonObject implements RRateLimiter @Override public RFuture availablePermitsAsync() { - return commandExecutor.writeAsync(getName(), LongCodec.INSTANCE, RedisCommands.GET_LONG, getValueName()); + return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_LONG, + "local rate = redis.call('hget', KEYS[1], 'rate');" + + "local interval = redis.call('hget', KEYS[1], 'interval');" + + "local type = redis.call('hget', KEYS[1], 'type');" + + "assert(rate ~= false and interval ~= false and type ~= false, 'RateLimiter is not initialized')" + + + "local valueName = KEYS[2];" + + "if type == '1' then " + + "valueName = KEYS[3];" + + "end;" + + + "local currentValue = redis.call('get', valueName); " + + "if currentValue == false then " + + "redis.call('set', valueName, rate, 'px', interval); " + + "return rate; " + + "else " + + "return currentValue; " + + "end;", + Arrays.asList(getName(), getValueName(), getClientValueName())); } diff --git a/redisson/src/test/java/org/redisson/RedissonRateLimiterTest.java b/redisson/src/test/java/org/redisson/RedissonRateLimiterTest.java index 05d4ab93c..cb46015a2 100644 --- a/redisson/src/test/java/org/redisson/RedissonRateLimiterTest.java +++ b/redisson/src/test/java/org/redisson/RedissonRateLimiterTest.java @@ -41,9 +41,9 @@ public class RedissonRateLimiterTest extends BaseTest { @Test public void testZeroTimeout() throws InterruptedException { RRateLimiter limiter = redisson.getRateLimiter("myLimiter"); - assertThat(limiter.availablePermits()).isEqualTo(0); limiter.trySetRate(RateType.OVERALL, 5, 1, RateIntervalUnit.SECONDS); - + assertThat(limiter.availablePermits()).isEqualTo(5); + assertThat(limiter.tryAcquire(1, 0, TimeUnit.SECONDS)).isTrue(); assertThat(limiter.tryAcquire(1, 0, TimeUnit.SECONDS)).isTrue(); assertThat(limiter.availablePermits()).isEqualTo(3);