use of org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
the class BKLogSegmentWriter method flushIfNeeded.
// Based on transmit buffer size, immediate flush, etc., should we flush the current
// packet now.
void flushIfNeeded() throws BKTransmitException, WriteException, InvalidEnvelopedEntryException, LockingException, FlushException {
if (outstandingBytes > transmissionThreshold) {
// If flush delay is disabled, flush immediately, else schedule appropriately.
if (0 == minDelayBetweenImmediateFlushMs) {
checkStateAndTransmit();
} else {
scheduleFlushWithDelayIfNeeded(new Callable<Void>() {
@Override
public Void call() throws Exception {
checkStateAndTransmit();
return null;
}
}, transmitSchedFutureRefUpdater);
// Timing here is not very important--the last flush failed and we should
// indicate this to the caller. The next flush may succeed and unset the
// scheduledFlushException in which case the next write will succeed (if the caller
// hasn't already closed the writer).
Exception exec = scheduledFlushExceptionUpdater.get(this);
if (exec != null) {
throw new FlushException("Last flush encountered an error while writing data to the backend", getLastTxId(), getLastTxIdAcknowledged(), exec);
}
}
}
}
use of org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
the class ZKLogStreamMetadataStore method executeRenameTxn.
private CompletableFuture<Void> executeRenameTxn(String oldLogPath, String newLogPath, LinkedList<Op> createOps, LinkedList<Op> deleteOps) {
CompletableFuture<Void> future = FutureUtils.createFuture();
List<Op> zkOps = Lists.newArrayListWithExpectedSize(createOps.size() + deleteOps.size());
zkOps.addAll(createOps);
zkOps.addAll(deleteOps);
if (LOG.isDebugEnabled()) {
for (Op op : zkOps) {
if (op instanceof Create) {
Create create = (Create) op;
LOG.debug("op : create {}", create.getPath());
} else if (op instanceof Delete) {
Delete delete = (Delete) op;
LOG.debug("op : delete {}, record = {}", delete.getPath(), op.toRequestRecord());
} else {
LOG.debug("op : {}", op);
}
}
}
try {
zooKeeperClient.get().multi(zkOps, (rc, path, ctx, opResults) -> {
if (Code.OK.intValue() == rc) {
future.complete(null);
} else if (Code.NODEEXISTS.intValue() == rc) {
future.completeExceptionally(new LogExistsException("Someone just created new log " + newLogPath));
} else if (Code.NOTEMPTY.intValue() == rc) {
future.completeExceptionally(new LockingException(oldLogPath + LOCK_PATH, "Someone is holding a lock on log " + oldLogPath));
} else {
future.completeExceptionally(new ZKException("Failed to rename log " + oldLogPath + " to " + newLogPath + " at path " + path, Code.get(rc)));
}
}, null);
} catch (ZooKeeperConnectionException e) {
future.completeExceptionally(e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
future.completeExceptionally(e);
}
return future;
}
use of org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
the class TestDistributedLock method testCheckWriteLockFailureWhenLockIsAcquiredByOthers.
@Test(timeout = 60000)
public void testCheckWriteLockFailureWhenLockIsAcquiredByOthers() throws Exception {
String lockPath = "/test-check-write-lock-failure-when-lock-is-acquired-by-others-" + System.currentTimeMillis();
String clientId = "test-check-write-lock-failure";
createLockPath(zkc.get(), lockPath);
SessionLockFactory lockFactory0 = createLockFactory(clientId, zkc0);
ZKDistributedLock lock0 = new ZKDistributedLock(lockStateExecutor, lockFactory0, lockPath, Long.MAX_VALUE, NullStatsLogger.INSTANCE);
Utils.ioResult(lock0.asyncAcquire());
Pair<String, Long> lockId0_1 = ((ZKSessionLock) lock0.getInternalLock()).getLockId();
List<String> children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertTrue(lock0.haveLock());
assertEquals(lockId0_1, Utils.ioResult(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
// expire the session
ZooKeeperClientUtils.expireSession(zkc0, zkServers, sessionTimeoutMs);
// reacquire the lock and wait reacquire completed
checkLockAndReacquire(lock0, true);
Pair<String, Long> lockId0_2 = ((ZKSessionLock) lock0.getInternalLock()).getLockId();
assertFalse("New lock should be created under different session", lockId0_1.equals(lockId0_2));
children = getLockWaiters(zkc, lockPath);
assertEquals(1, children.size());
assertTrue(lock0.haveLock());
assertEquals(lockId0_2, Utils.ioResult(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
SessionLockFactory lockFactory = createLockFactory(clientId, zkc);
final ZKDistributedLock lock1 = new ZKDistributedLock(lockStateExecutor, lockFactory, lockPath, Long.MAX_VALUE, NullStatsLogger.INSTANCE);
final CountDownLatch lockLatch = new CountDownLatch(1);
Thread lockThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Utils.ioResult(lock1.asyncAcquire());
lockLatch.countDown();
} catch (Exception e) {
logger.error("Failed on locking lock1 : ", e);
}
}
}, "lock-thread");
lockThread.start();
// ensure lock1 is waiting for lock0
do {
Thread.sleep(1);
children = getLockWaiters(zkc, lockPath);
} while (children.size() < 2);
// expire the session
ZooKeeperClientUtils.expireSession(zkc0, zkServers, sessionTimeoutMs);
lockLatch.await();
lockThread.join();
try {
checkLockAndReacquire(lock0, true);
fail("Should fail on checking write lock since lock is acquired by lock1");
} catch (LockingException le) {
// expected
}
try {
checkLockAndReacquire(lock0, false);
fail("Should fail on checking write lock since lock is acquired by lock1");
} catch (LockingException le) {
// expected
}
}
use of org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
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.executeOrdered(lockPath, () -> 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 org.apache.distributedlog.exceptions.LockingException in project bookkeeper by apache.
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(), 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))));
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(), Utils.ioResult(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
assertEquals(State.WAITING, lock1.getLockState());
assertEquals(lock1.getLockId(), Utils.ioResult(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(), 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))));
awaitState(State.WAITING, lock0_1);
assertEquals(lock0_1.getLockId(), Utils.ioResult(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(), Utils.ioResult(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(), Utils.ioResult(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
} else {
children = getLockWaiters(zkc, lockPath);
assertEquals(2, children.size());
assertEquals(State.CLAIMED, lock1.getLockState());
assertEquals(lock1.getLockId(), Utils.ioResult(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
assertEquals(State.WAITING, lock0_1.getLockState());
assertEquals(lock0_1.getLockId(), Utils.ioResult(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(), Utils.ioResult(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
}
}
Aggregations