diff --git a/redisson/src/main/java/org/redisson/RedissonPermitExpirableSemaphore.java b/redisson/src/main/java/org/redisson/RedissonPermitExpirableSemaphore.java index ecd3963d5..aca9b9b4b 100644 --- a/redisson/src/main/java/org/redisson/RedissonPermitExpirableSemaphore.java +++ b/redisson/src/main/java/org/redisson/RedissonPermitExpirableSemaphore.java @@ -552,22 +552,25 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen public boolean tryRelease(String permitId) { return get(tryReleaseAsync(permitId)); } - - @Override + public RFuture tryReleaseAsync(String permitId) { if (permitId == null) { throw new IllegalArgumentException("permitId can't be null"); } return commandExecutor.evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, - "local removed = redis.call('zrem', KEYS[3], ARGV[1]);" + - "if tonumber(removed) ~= 1 then " + - "return 0;" + - "end;" + - "local value = redis.call('incrby', KEYS[1], ARGV[2]); " + - "redis.call('publish', KEYS[2], value); " + - "return 1;", - Arrays.asList(getRawName(), getChannelName(), timeoutName), permitId, 1); + "local expire = redis.call('zscore', KEYS[3], ARGV[1]);" + + "local removed = redis.call('zrem', KEYS[3], ARGV[1]);" + + "if tonumber(removed) ~= 1 then " + + "return 0;" + + "end;" + + "local value = redis.call('incrby', KEYS[1], ARGV[2]); " + + "redis.call('publish', KEYS[2], value); " + + "if tonumber(expire) <= tonumber(ARGV[3]) then " + + "return 0;" + + "end;" + + "return 1;", + Arrays.asList(getRawName(), getChannelName(), timeoutName), permitId, 1, System.currentTimeMillis()); } @Override diff --git a/redisson/src/test/java/org/redisson/RedissonPermitExpirableSemaphoreTest.java b/redisson/src/test/java/org/redisson/RedissonPermitExpirableSemaphoreTest.java index 1d1e759c9..f84781686 100644 --- a/redisson/src/test/java/org/redisson/RedissonPermitExpirableSemaphoreTest.java +++ b/redisson/src/test/java/org/redisson/RedissonPermitExpirableSemaphoreTest.java @@ -220,6 +220,16 @@ public class RedissonPermitExpirableSemaphoreTest extends BaseConcurrentTest { }); } + @Test + public void testReleaseExpired() throws InterruptedException { + RPermitExpirableSemaphore s = redisson.getPermitExpirableSemaphore("test"); + s.trySetPermits(1); + String permitId = s.tryAcquire(100, 100, TimeUnit.MILLISECONDS); + Thread.sleep(200); + boolean released = s.tryRelease(permitId); + assertThat(released).isFalse(); + } + @Test public void testConcurrency_SingleInstance() throws InterruptedException { final AtomicInteger lockedCounter = new AtomicInteger();