use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testLockWhenSiblingUseSameLockId.
private void testLockWhenSiblingUseSameLockId(long timeout, final boolean isUnlock) throws Exception {
String lockPath = "/test-lock-when-sibling-use-same-lock-id-" + timeout + "-" + isUnlock + "-" + System.currentTimeMillis();
String clientId = "client-id";
createLockPath(zkc.get(), lockPath);
final ZKSessionLock lock0 = new ZKSessionLock(zkc0, lockPath, clientId, lockStateExecutor);
final ZKSessionLock lock1 = new ZKSessionLock(zkc0, lockPath, clientId, lockStateExecutor);
lock0.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
List<String> children = getLockWaiters(zkc0, lockPath);
assertEquals(1, children.size());
assertEquals(State.CLAIMED, lock0.getLockState());
assertEquals(lock0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
lock1.tryLock(timeout, TimeUnit.MILLISECONDS);
children = getLockWaiters(zkc0, lockPath);
assertEquals(2, children.size());
assertEquals(State.CLAIMED, lock0.getLockState());
assertEquals(lock0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
assertEquals(State.CLAIMED, lock1.getLockState());
assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(1))));
if (isUnlock) {
lock0.unlock();
assertEquals(State.CLOSED, lock0.getLockState());
children = getLockWaiters(zkc0, lockPath);
assertEquals(1, children.size());
assertEquals(State.CLAIMED, lock1.getLockState());
assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
lock1.unlock();
} else {
ZooKeeperClientUtils.expireSession(zkc0, zkServers, sessionTimeoutMs);
final CountDownLatch latch = new CountDownLatch(1);
lockStateExecutor.submit(lockPath, new SafeRunnable() {
@Override
public void safeRun() {
latch.countDown();
}
});
latch.await();
children = getLockWaiters(zkc, lockPath);
assertEquals(0, children.size());
assertEquals(State.EXPIRED, lock0.getLockState());
assertEquals(State.EXPIRED, lock1.getLockState());
}
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testLockWhenSiblingUseDifferentLockId.
private void testLockWhenSiblingUseDifferentLockId(long timeout, final boolean isUnlock) throws Exception {
String lockPath = "/test-lock-when-sibling-use-different-lock-id-" + timeout + "-" + isUnlock + "-" + System.currentTimeMillis();
String clientId0 = "client-id-0";
String clientId1 = "client-id-1";
createLockPath(zkc.get(), lockPath);
final ZKSessionLock lock0_0 = new ZKSessionLock(zkc0, lockPath, clientId0, lockStateExecutor);
final ZKSessionLock lock0_1 = new ZKSessionLock(zkc0, lockPath, clientId0, lockStateExecutor);
final ZKSessionLock lock1 = new ZKSessionLock(zkc, lockPath, clientId1, lockStateExecutor);
lock0_0.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
// lock1 wait for the lock ownership.
final CountDownLatch lock1DoneLatch = new CountDownLatch(1);
Thread lock1Thread = new Thread(new Runnable() {
@Override
public void run() {
try {
lock1.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
lock1DoneLatch.countDown();
} catch (LockingException e) {
logger.error("Failed on locking lock1 : ", e);
}
}
}, "lock1-thread");
lock1Thread.start();
// check lock1 is waiting for lock0_0
List<String> children = awaitWaiters(2, zkc, lockPath);
assertEquals(2, children.size());
assertEquals(State.CLAIMED, lock0_0.getLockState());
assertEquals(lock0_0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
awaitState(State.WAITING, lock1);
assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(1))));
final CountDownLatch lock0DoneLatch = new CountDownLatch(1);
final AtomicReference<String> ownerFromLock0 = new AtomicReference<String>(null);
Thread lock0Thread = null;
if (timeout == 0) {
try {
lock0_1.tryLock(0, TimeUnit.MILLISECONDS);
fail("Should fail on locking if sibling is using differnt lock id.");
} catch (OwnershipAcquireFailedException oafe) {
assertEquals(clientId0, oafe.getCurrentOwner());
}
assertEquals(State.CLOSED, lock0_1.getLockState());
children = getLockWaiters(zkc, lockPath);
assertEquals(2, children.size());
assertEquals(State.CLAIMED, lock0_0.getLockState());
assertEquals(lock0_0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
assertEquals(State.WAITING, lock1.getLockState());
assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(1))));
} else {
lock0Thread = new Thread(new Runnable() {
@Override
public void run() {
try {
lock0_1.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
if (isUnlock) {
lock0DoneLatch.countDown();
}
} catch (OwnershipAcquireFailedException oafe) {
if (!isUnlock) {
ownerFromLock0.set(oafe.getCurrentOwner());
lock0DoneLatch.countDown();
}
} catch (LockingException le) {
logger.error("Failed on locking lock0_1 : ", le);
}
}
}, "lock0-thread");
lock0Thread.start();
// check lock1 is waiting for lock0_0
children = awaitWaiters(3, zkc, lockPath);
assertEquals(3, children.size());
assertEquals(State.CLAIMED, lock0_0.getLockState());
assertEquals(lock0_0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
awaitState(State.WAITING, lock1);
assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(1))));
awaitState(State.WAITING, lock0_1);
assertEquals(lock0_1.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(2))));
}
if (isUnlock) {
lock0_0.unlock();
} else {
ZooKeeperClientUtils.expireSession(zkc0, zkServers, sessionTimeoutMs);
}
lock1DoneLatch.await();
lock1Thread.join();
// check the state of lock0_0
if (isUnlock) {
assertEquals(State.CLOSED, lock0_0.getLockState());
} else {
assertEquals(State.EXPIRED, lock0_0.getLockState());
}
if (timeout == 0) {
children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertEquals(State.CLAIMED, lock1.getLockState());
assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
} else {
assertNotNull(lock0Thread);
if (!isUnlock) {
// both lock0_0 and lock0_1 would be expired
lock0DoneLatch.await();
lock0Thread.join();
assertEquals(clientId0, ownerFromLock0.get());
assertEquals(State.CLOSED, lock0_1.getLockState());
children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertEquals(State.CLAIMED, lock1.getLockState());
assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
} else {
children = getLockWaiters(zkc, lockPath);
assertEquals(2, children.size());
assertEquals(State.CLAIMED, lock1.getLockState());
assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
assertEquals(State.WAITING, lock0_1.getLockState());
assertEquals(lock0_1.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(1))));
}
}
lock1.unlock();
if (timeout != 0 && isUnlock) {
lock0DoneLatch.await();
lock0Thread.join();
children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertEquals(State.CLAIMED, lock0_1.getLockState());
assertEquals(lock0_1.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
}
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testWaitForLockReleased.
/**
* Test lock wait for the lock owner to release the lock. The lock waiter should acquire lock successfully
* if the lock owner unlock or it is expired.
*
* @param lockPath
* lock path
* @param isUnlock
* whether to unlock or expire the lock
* @throws Exception
*/
private void testWaitForLockReleased(String lockPath, boolean isUnlock) throws Exception {
String clientId0 = "test-wait-for-lock-released-0-" + System.currentTimeMillis();
String clientId1 = "test-wait-for-lock-released-1-" + System.currentTimeMillis();
createLockPath(zkc.get(), lockPath);
final ZKSessionLock lock0 = new ZKSessionLock(zkc0, lockPath, clientId0, lockStateExecutor);
final ZKSessionLock lock1 = new ZKSessionLock(zkc, lockPath, clientId1, lockStateExecutor);
lock0.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
// verification after lock0 lock
assertEquals(State.CLAIMED, lock0.getLockState());
List<String> children = getLockWaiters(zkc0, lockPath);
assertEquals(1, children.size());
assertEquals(lock0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
final CountDownLatch lock1DoneLatch = new CountDownLatch(1);
Thread lock1Thread = new Thread(new Runnable() {
@Override
public void run() {
try {
lock1.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
lock1DoneLatch.countDown();
} catch (LockingException e) {
logger.error("Failed on locking lock1 : ", e);
}
}
}, "lock1-thread");
lock1Thread.start();
// ensure lock1 is waiting for lock0
children = awaitWaiters(2, zkc, lockPath);
if (isUnlock) {
lock0.unlock();
} else {
ZooKeeperClientUtils.expireSession(zkc0, zkServers, sessionTimeoutMs);
}
lock1DoneLatch.await();
lock1Thread.join();
// verification after lock2 lock
if (isUnlock) {
assertEquals(State.CLOSED, lock0.getLockState());
} else {
assertEquals(State.EXPIRED, lock0.getLockState());
}
assertEquals(State.CLAIMED, lock1.getLockState());
children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
lock1.unlock();
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testLockWhenPreviousLockZnodeStillExists.
@Test(timeout = 60000)
public void testLockWhenPreviousLockZnodeStillExists() throws Exception {
String lockPath = "/test-lock-when-previous-lock-znode-still-exists-" + System.currentTimeMillis();
String clientId = "client-id";
ZooKeeper zk = zkc.get();
createLockPath(zk, lockPath);
final ZKSessionLock lock0 = new ZKSessionLock(zkc0, lockPath, clientId, lockStateExecutor);
// lock0 lock
lock0.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
// simulate lock0 expires but znode still exists
final DistributedLockContext context1 = new DistributedLockContext();
context1.addLockId(lock0.getLockId());
final ZKSessionLock lock1 = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor, 60000, NullStatsLogger.INSTANCE, context1);
lock1.tryLock(0L, TimeUnit.MILLISECONDS);
assertEquals(State.CLAIMED, lock1.getLockState());
lock1.unlock();
final DistributedLockContext context2 = new DistributedLockContext();
context2.addLockId(lock0.getLockId());
final ZKSessionLock lock2 = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor, 60000, NullStatsLogger.INSTANCE, context2);
lock2.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
assertEquals(State.CLAIMED, lock2.getLockState());
lock2.unlock();
lock0.unlock();
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testLockAfterUnlock.
/**
* Test lock after unlock is called.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testLockAfterUnlock() throws Exception {
String lockPath = "/test-lock-after-unlock";
String clientId = "test-lock-after-unlock";
ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor);
lock.unlock();
assertEquals(State.CLOSED, lock.getLockState());
try {
lock.tryLock(0, TimeUnit.MILLISECONDS);
fail("Should fail on tryLock since lock state has changed.");
} catch (LockStateChangedException lsce) {
// expected
}
assertEquals(State.CLOSED, lock.getLockState());
try {
lock.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
fail("Should fail on tryLock immediately if lock state has changed.");
} catch (LockStateChangedException lsce) {
// expected
}
assertEquals(State.CLOSED, lock.getLockState());
}
Aggregations