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 org.redisson.core.RLock;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
/** /**
* Lock will be removed automatically if client disconnects. * Lock will be removed automatically if client disconnects.
@ -111,18 +112,26 @@ public class RedissonReadLock extends RedissonLock implements RLock {
} }
Future<Boolean> forceUnlockAsync() { Future<Boolean> forceUnlockAsync() {
cancelExpirationRenewal(); Future<Boolean> result = commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, "if (redis.call('hget', KEYS[1], 'mode') == 'read') then " +
"if (redis.call('hdel', KEYS[1], ARGV[2]) == 1) then " +
"if (redis.call('hlen', KEYS[1]) == 1) then " +
"redis.call('del', KEYS[1]); " + "redis.call('del', KEYS[1]); " +
"redis.call('publish', KEYS[2], ARGV[1]); " + "redis.call('publish', KEYS[2], ARGV[1]); " +
"end; " +
"return 1; " + "return 1; " +
"else " + "else " +
"return 0; " + "return 0; " +
"end;", "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 @Override

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

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

Loading…
Cancel
Save