Fixed - RPermitExpirableSemaphore.release(java.util.List) shouldn't release permits if one of them doesn't exist #6343

Signed-off-by: xuxiaolei <seakider@gmail.com>
pull/6348/head
seakider 2 months ago committed by xuxiaolei
parent cd7f26b19a
commit ee3d4c2e37

@ -657,6 +657,12 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen
}
return commandExecutor.syncedEvalWithRetry(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_INTEGER,
"for i = 4, #ARGV, 1 do " +
"local expire = redis.call('zscore', KEYS[3], ARGV[i]);" +
"if expire== false or tonumber(expire) <= tonumber(ARGV[2]) then " +
"return 0;" +
"end; " +
"end; " +
"local expiredIds = redis.call('zrangebyscore', KEYS[3], 0, ARGV[2], 'limit', 0, -1); " +
"if #expiredIds > 0 then " +
"redis.call('zrem', KEYS[3], unpack(expiredIds)); " +
@ -670,9 +676,6 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen
"table.insert(keys, ARGV[i]); " +
"end; " +
"local removed = redis.call('zrem', KEYS[3], unpack(keys)); " +
"if tonumber(removed) == 0 then " +
"return 0;" +
"end; " +
"redis.call('incrby', KEYS[1], removed); " +
"redis.call(ARGV[3], KEYS[2], removed); " +
"return removed;",
@ -733,7 +736,10 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen
throw new CompletionException(e);
}
if (res == permitsIds.size()) {
// if (res == permitsIds.size()) {
// return null;
// }
if (res != 0) {
return null;
}
throw new CompletionException(new IllegalArgumentException("Permits with ids " + permitsIds + " have already been released or don't exist"));
@ -931,7 +937,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen
if (e != null) {
throw new CompletionException(e);
}
if (res == 0) {
throw new CompletionException(new IllegalArgumentException("Permit with id " + permitId + " has already been released or doesn't exist"));
}

@ -476,6 +476,7 @@ public class RedissonPermitExpirableSemaphoreTest extends BaseConcurrentTest {
assertThat(semaphore.availablePermits()).isEqualTo(10);
Assertions.assertThrows(RedisException.class, () -> semaphore.release(permitsIds));
}
@Test
@ -553,6 +554,31 @@ public class RedissonPermitExpirableSemaphoreTest extends BaseConcurrentTest {
assertThat(released).isEqualTo(0);
assertThat(s.availablePermits()).isEqualTo(10);
}
@Test
public void testReleaseManyWithout() throws InterruptedException {
RPermitExpirableSemaphore s = redisson.getPermitExpirableSemaphore("test");
s.trySetPermits(10);
List<String> timedPermitsIds = s.acquire(2,100, TimeUnit.MILLISECONDS);
List<String> permitsIds = s.tryAcquire(8);
List<String> permitsIdsFirstPart = permitsIds.subList(0, 2);
int released = s.tryRelease(permitsIdsFirstPart);
assertThat(released).isEqualTo(2);
assertThat(s.availablePermits()).isEqualTo(2);
Thread.sleep(100);
Assertions.assertThrows(RedisException.class, () -> s.release(timedPermitsIds));
assertThat(s.availablePermits()).isEqualTo(4);
List<String> permitsIdsThirdPart = permitsIds.subList(4, 6);
permitsIdsThirdPart.addAll(permitsIdsFirstPart);
Assertions.assertThrows(RedisException.class, () -> s.release(permitsIdsThirdPart));
assertThat(s.availablePermits()).isEqualTo(4);
}
@Test
public void testGetLeaseTime() throws InterruptedException {

Loading…
Cancel
Save