use of org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
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(), Utils.ioResult(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(), Utils.ioResult(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
awaitState(State.WAITING, lock1);
assertEquals(lock1.getLockId(), Utils.ioResult(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(), Utils.ioResult(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
}
use of org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
the class BKAbstractLogWriter method closeOldLogSegmentAndStartNewOneWithPermit.
private CompletableFuture<BKLogSegmentWriter> closeOldLogSegmentAndStartNewOneWithPermit(final BKLogSegmentWriter oldSegmentWriter, final BKLogWriteHandler writeHandler, final long startTxId, final boolean bestEffort, final boolean allowMaxTxID) {
final PermitManager.Permit switchPermit = bkDistributedLogManager.getLogSegmentRollingPermitManager().acquirePermit();
if (switchPermit.isAllowed()) {
return FutureUtils.ensure(FutureUtils.rescue(closeOldLogSegmentAndStartNewOne(oldSegmentWriter, writeHandler, startTxId, bestEffort, allowMaxTxID), // rescue function
cause -> {
if (cause instanceof LockingException) {
LOG.warn("We lost lock during completeAndClose log segment for {}." + "Disable ledger rolling until it is recovered : ", writeHandler.getFullyQualifiedName(), cause);
bkDistributedLogManager.getLogSegmentRollingPermitManager().disallowObtainPermits(switchPermit);
return FutureUtils.value(oldSegmentWriter);
} else if (cause instanceof ZKException) {
ZKException zke = (ZKException) cause;
if (ZKException.isRetryableZKException(zke)) {
LOG.warn("Encountered zookeeper connection issues during completeAndClose " + "log segment for {}. " + "Disable ledger rolling until it is recovered : {}", writeHandler.getFullyQualifiedName(), zke.getKeeperExceptionCode());
bkDistributedLogManager.getLogSegmentRollingPermitManager().disallowObtainPermits(switchPermit);
return FutureUtils.value(oldSegmentWriter);
}
}
return FutureUtils.exception(cause);
}), // ensure function
() -> bkDistributedLogManager.getLogSegmentRollingPermitManager().releasePermit(switchPermit));
} else {
bkDistributedLogManager.getLogSegmentRollingPermitManager().releasePermit(switchPermit);
return FutureUtils.value(oldSegmentWriter);
}
}
use of org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
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(), Utils.ioResult(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(), Utils.ioResult(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
awaitState(State.WAITING, lock1_1);
assertEquals(lock1_1.getLockId(), Utils.ioResult(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(), Utils.ioResult(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
lock1_1.unlock();
}
use of org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
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(), Utils.ioResult(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(), Utils.ioResult(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
lock1.unlock();
}
use of org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
the class TestAsyncReaderWriter method testAsyncWriteWithMinDelayBetweenFlushesFlushFailure.
@Test(timeout = 60000)
public void testAsyncWriteWithMinDelayBetweenFlushesFlushFailure() throws Exception {
String name = runtime.getMethodName();
DistributedLogConfiguration confLocal = new DistributedLogConfiguration();
confLocal.loadConf(testConf);
confLocal.setOutputBufferSize(0);
confLocal.setImmediateFlushEnabled(true);
confLocal.setMinDelayBetweenImmediateFlushMs(1);
URI uri = createDLMURI("/" + name);
ensureURICreated(uri);
Namespace namespace = NamespaceBuilder.newBuilder().conf(confLocal).uri(uri).clientId("gabbagoo").build();
DistributedLogManager dlm = namespace.openLog(name);
Namespace namespace1 = NamespaceBuilder.newBuilder().conf(confLocal).uri(uri).clientId("tortellini").build();
DistributedLogManager dlm1 = namespace1.openLog(name);
int txid = 1;
BKAsyncLogWriter writer = (BKAsyncLogWriter) (dlm.startAsyncLogSegmentNonPartitioned());
// First write succeeds since lock isnt checked until transmit, which is scheduled
Utils.ioResult(writer.write(DLMTestUtil.getLogRecordInstance(txid++)));
writer.flushAndCommit();
BKLogSegmentWriter perStreamWriter = writer.getCachedLogWriter();
DistributedLock lock = perStreamWriter.getLock();
Utils.ioResult(lock.asyncClose());
// Get second writer, steal lock
BKAsyncLogWriter writer2 = (BKAsyncLogWriter) (dlm1.startAsyncLogSegmentNonPartitioned());
try {
// Succeeds, kicks off scheduked flush
writer.write(DLMTestUtil.getLogRecordInstance(txid++));
// Succeeds, kicks off scheduled flush
Thread.sleep(100);
Utils.ioResult(writer.write(DLMTestUtil.getLogRecordInstance(txid++)));
fail("should have thrown");
} catch (LockingException ex) {
LOG.debug("caught exception ", ex);
}
writer.close();
dlm.close();
}
Aggregations