use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testLockUseSameClientIdButDifferentSessions.
private void testLockUseSameClientIdButDifferentSessions(boolean isUnlock) throws Exception {
String lockPath = "/test-lock-use-same-client-id-but-different-sessions-" + isUnlock + System.currentTimeMillis();
String clientId = "test-lock-use-same-client-id-but-different-sessions";
createLockPath(zkc.get(), lockPath);
final ZKSessionLock lock0 = new ZKSessionLock(zkc0, lockPath, clientId, lockStateExecutor);
lock0.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
// lock1_0 couldn't claim ownership since owner is in a different zk session.
final ZKSessionLock lock1_0 = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor);
try {
lock1_0.tryLock(0, TimeUnit.MILLISECONDS);
fail("Should fail locking since the lock is held in a different zk session.");
} catch (OwnershipAcquireFailedException oafe) {
assertEquals(clientId, oafe.getCurrentOwner());
}
assertEquals(State.CLOSED, lock1_0.getLockState());
List<String> children = getLockWaiters(zkc0, lockPath);
assertEquals(1, children.size());
assertEquals(lock0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
// lock1_1 would wait the ownership
final ZKSessionLock lock1_1 = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor);
final CountDownLatch lock1DoneLatch = new CountDownLatch(1);
Thread lock1Thread = new Thread(new Runnable() {
@Override
public void run() {
try {
lock1_1.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
children = awaitWaiters(2, zkc, lockPath);
logger.info("Found {} lock waiters : {}", children.size(), children);
assertEquals(2, children.size());
assertEquals(State.CLAIMED, lock0.getLockState());
assertEquals(lock0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
awaitState(State.WAITING, lock1_1);
assertEquals(lock1_1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(1))));
if (isUnlock) {
lock0.unlock();
} else {
ZooKeeperClientUtils.expireSession(zkc0, zkServers, sessionTimeoutMs);
}
lock1DoneLatch.await();
lock1Thread.join();
// verification
if (isUnlock) {
assertEquals(State.CLOSED, lock0.getLockState());
} else {
assertEquals(State.EXPIRED, lock0.getLockState());
}
assertEquals(State.CLAIMED, lock1_1.getLockState());
children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertEquals(lock1_1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
lock1_1.unlock();
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testBasicLockUnlock.
/**
* Test Basic Lock and Unlock
*
* - lock should succeed if there is no lock held
* - lock should fail on a success lock
* - unlock should release the held lock
*
* @param timeout
* timeout to wait for the lock
* @throws Exception
*/
private void testBasicLockUnlock(long timeout) throws Exception {
String lockPath = "/test-basic-lock-unlock-" + timeout + System.currentTimeMillis();
String clientId = "test-basic-lock-unlock";
createLockPath(zkc.get(), lockPath);
ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor);
// lock
lock.tryLock(timeout, TimeUnit.MILLISECONDS);
// verification after lock
assertEquals(State.CLAIMED, lock.getLockState());
List<String> children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertEquals(lock.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
// lock should fail on a success lock
try {
lock.tryLock(timeout, TimeUnit.MILLISECONDS);
fail("Should fail on locking a failure lock.");
} catch (LockStateChangedException lsce) {
// expected
}
assertEquals(State.CLAIMED, lock.getLockState());
children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertEquals(lock.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
// unlock
lock.unlock();
// verification after unlock
assertEquals(State.CLOSED, lock.getLockState());
assertEquals(0, getLockWaiters(zkc, lockPath).size());
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testSessionExpiredBeforeLock.
/**
* Test Session Expired Before Lock does locking. The lock should be closed since
* all zookeeper operations would be failed.
*
* @param timeout
* timeout to wait for the lock
* @throws Exception
*/
private void testSessionExpiredBeforeLock(long timeout) throws Exception {
String lockPath = "/test-session-expired-before-lock-" + timeout + "-" + System.currentTimeMillis();
String clientId = "test-session-expired-before-lock-" + System.currentTimeMillis();
createLockPath(zkc.get(), lockPath);
final AtomicInteger expireCounter = new AtomicInteger(0);
final CountDownLatch expiredLatch = new CountDownLatch(1);
LockListener listener = new LockListener() {
@Override
public void onExpired() {
expireCounter.incrementAndGet();
}
};
final ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor).setLockListener(listener);
// expire session
ZooKeeperClientUtils.expireSession(zkc, zkServers, sessionTimeoutMs);
// submit a runnable to lock state executor to ensure any state changes happened when session expired
lockStateExecutor.submit(lockPath, new SafeRunnable() {
@Override
public void safeRun() {
expiredLatch.countDown();
}
});
expiredLatch.await();
// no watcher was registered if never acquired lock successfully
assertEquals(State.INIT, lock.getLockState());
try {
lock.tryLock(timeout, TimeUnit.MILLISECONDS);
fail("Should fail locking using an expired lock");
} catch (LockingException le) {
assertTrue(le.getCause() instanceof KeeperException.SessionExpiredException);
}
assertEquals(State.CLOSED, lock.getLockState());
List<String> children = getLockWaiters(zkc, lockPath);
assertEquals(0, children.size());
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testTryAcquireTimeout.
/**
* Test try acquire timeout.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testTryAcquireTimeout() throws Exception {
String name = testNames.getMethodName();
String lockPath = "/" + name;
String clientId = name;
createLockPath(zkc.get(), lockPath);
ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor, 1, /* op timeout */
NullStatsLogger.INSTANCE, new DistributedLockContext());
try {
FailpointUtils.setFailpoint(FailpointUtils.FailPointName.FP_LockTryAcquire, new DelayFailpointAction(60 * 60 * 1000));
lock.tryLock(0, TimeUnit.MILLISECONDS);
assertEquals(State.CLOSED, lock.getLockState());
} catch (LockingException le) {
} catch (Exception e) {
fail("expected locking exception");
} finally {
FailpointUtils.removeFailpoint(FailpointUtils.FailPointName.FP_LockTryAcquire);
}
}
use of com.twitter.distributedlog.lock.ZKSessionLock in project distributedlog by twitter.
the class TestZKSessionLock method testSessionExpiredForLockWaiter.
@Test(timeout = 60000)
public void testSessionExpiredForLockWaiter() throws Exception {
String lockPath = "/test-session-expired-for-lock-waiter";
String clientId0 = "test-session-expired-for-lock-waiter-0";
String clientId1 = "test-session-expired-for-lock-waiter-1";
createLockPath(zkc.get(), lockPath);
final ZKSessionLock lock0 = new ZKSessionLock(zkc0, lockPath, clientId0, lockStateExecutor);
lock0.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
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 ZKSessionLock lock1 = new ZKSessionLock(zkc, lockPath, clientId1, lockStateExecutor);
final CountDownLatch lock1DoneLatch = new CountDownLatch(1);
Thread lock1Thread = new Thread(new Runnable() {
@Override
public void run() {
try {
lock1.tryLock(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (OwnershipAcquireFailedException oafe) {
lock1DoneLatch.countDown();
} catch (LockingException e) {
logger.error("Failed on locking lock1 : ", e);
}
}
}, "lock1-thread");
lock1Thread.start();
// check lock1 is waiting for lock0
children = awaitWaiters(2, zkc, lockPath);
assertEquals(2, children.size());
assertEquals(State.CLAIMED, lock0.getLockState());
assertEquals(lock0.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))));
// expire lock1
ZooKeeperClientUtils.expireSession(zkc, zkServers, sessionTimeoutMs);
lock1DoneLatch.countDown();
lock1Thread.join();
assertEquals(State.CLAIMED, lock0.getLockState());
assertEquals(State.CLOSED, lock1.getLockState());
children = getLockWaiters(zkc0, lockPath);
assertEquals(1, children.size());
assertEquals(lock0.getLockId(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
}
Aggregations