ReadWriteLock forceUnlock fixed

pull/337/head
Nikita 9 years ago
parent ee3704356b
commit 41ee17d2e1

@ -27,6 +27,7 @@ import org.redisson.command.CommandExecutor;
import org.redisson.core.RLock;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
/**
* Lock will be removed automatically if client disconnects.
@ -111,18 +112,26 @@ public class RedissonReadLock extends RedissonLock implements RLock {
}
Future<Boolean> forceUnlockAsync() {
cancelExpirationRenewal();
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
"if (redis.call('hdel', KEYS[1], ARGV[2]) == 1) then " +
"if (redis.call('hlen', KEYS[1]) == 1) then " +
Future<Boolean> result = commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
"if (redis.call('hget', KEYS[1], 'mode') == 'read') then " +
"redis.call('del', KEYS[1]); " +
"redis.call('publish', KEYS[2], ARGV[1]); " +
"end; " +
"return 1; " +
"else " +
"return 0; " +
"end;",
Arrays.<Object>asList(getName(), getChannelName()), unlockMessage, getLockName());
Arrays.<Object>asList(getName(), getChannelName()), unlockMessage);
result.addListener(new FutureListener<Boolean>() {
@Override
public void operationComplete(Future<Boolean> future) throws Exception {
if (future.isSuccess() && future.getNow()) {
cancelExpirationRenewal();
}
}
});
return result;
}
@Override

@ -27,6 +27,7 @@ import org.redisson.command.CommandExecutor;
import org.redisson.core.RLock;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
/**
* Lock will be removed automatically if client disconnects.
@ -113,8 +114,7 @@ public class RedissonWriteLock extends RedissonLock implements RLock {
}
Future<Boolean> forceUnlockAsync() {
cancelExpirationRenewal();
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
Future<Boolean> result = commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
"if (redis.call('hget', KEYS[1], 'mode') == 'write') then " +
"redis.call('del', KEYS[1]); " +
"redis.call('publish', KEYS[2], ARGV[1]); " +
@ -123,6 +123,17 @@ public class RedissonWriteLock extends RedissonLock implements RLock {
"return 0; " +
"end;",
Arrays.<Object>asList(getName(), getChannelName()), unlockMessage);
result.addListener(new FutureListener<Boolean>() {
@Override
public void operationComplete(Future<Boolean> future) throws Exception {
if (future.isSuccess() && future.getNow()) {
cancelExpirationRenewal();
}
}
});
return result;
}
@Override

@ -11,6 +11,7 @@ import org.junit.Assert;
import org.junit.Test;
import org.redisson.core.RLock;
import org.redisson.core.RReadWriteLock;
import static org.assertj.core.api.Assertions.*;
public class RedissonReadWriteLockTest extends BaseConcurrentTest {
@ -119,14 +120,26 @@ public class RedissonReadWriteLockTest extends BaseConcurrentTest {
@Test
public void testForceUnlock() {
RReadWriteLock lock = redisson.getReadWriteLock("lock");
RLock readLock = lock.readLock();
readLock.lock();
Assert.assertTrue(readLock.isLocked());
readLock.forceUnlock();
Assert.assertFalse(readLock.isLocked());
assertThat(readLock.isLocked()).isTrue();
lock.writeLock().forceUnlock();
assertThat(readLock.isLocked()).isTrue();
lock.readLock().forceUnlock();
assertThat(readLock.isLocked()).isFalse();
RLock writeLock = lock.writeLock();
writeLock.lock();
assertThat(writeLock.isLocked()).isTrue();
lock.readLock().forceUnlock();
assertThat(writeLock.isLocked()).isTrue();
lock.writeLock().forceUnlock();
assertThat(writeLock.isLocked()).isFalse();
lock = redisson.getReadWriteLock("lock");
Assert.assertFalse(lock.readLock().isLocked());
assertThat(lock.readLock().isLocked()).isFalse();
assertThat(lock.writeLock().isLocked()).isFalse();
}
@Test

Loading…
Cancel
Save