Search in sources :

Example 6 with LockingException

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))));
}
Also used : OwnershipAcquireFailedException(org.apache.distributedlog.exceptions.OwnershipAcquireFailedException) LockingException(org.apache.distributedlog.exceptions.LockingException) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 7 with LockingException

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);
    }
}
Also used : AlreadyClosedException(org.apache.distributedlog.exceptions.AlreadyClosedException) ZKException(org.apache.distributedlog.exceptions.ZKException) AsyncAbortable(org.apache.distributedlog.io.AsyncAbortable) Logger(org.slf4j.Logger) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener) LockingException(org.apache.distributedlog.exceptions.LockingException) LoggerFactory(org.slf4j.LoggerFactory) PermitManager(org.apache.distributedlog.common.util.PermitManager) IOException(java.io.IOException) CompletableFuture(java.util.concurrent.CompletableFuture) FutureUtils(org.apache.bookkeeper.common.concurrent.FutureUtils) Function(java.util.function.Function) Abortable(org.apache.distributedlog.io.Abortable) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) UnexpectedException(org.apache.distributedlog.exceptions.UnexpectedException) AsyncCloseable(org.apache.distributedlog.io.AsyncCloseable) Closeable(java.io.Closeable) DynamicDistributedLogConfiguration(org.apache.distributedlog.config.DynamicDistributedLogConfiguration) Utils(org.apache.distributedlog.util.Utils) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Abortables(org.apache.distributedlog.io.Abortables) LockingException(org.apache.distributedlog.exceptions.LockingException) PermitManager(org.apache.distributedlog.common.util.PermitManager) ZKException(org.apache.distributedlog.exceptions.ZKException)

Example 8 with LockingException

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();
}
Also used : OwnershipAcquireFailedException(org.apache.distributedlog.exceptions.OwnershipAcquireFailedException) LockingException(org.apache.distributedlog.exceptions.LockingException) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 9 with LockingException

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();
}
Also used : LockingException(org.apache.distributedlog.exceptions.LockingException) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 10 with LockingException

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();
}
Also used : DynamicDistributedLogConfiguration(org.apache.distributedlog.config.DynamicDistributedLogConfiguration) DistributedLock(org.apache.distributedlog.lock.DistributedLock) LockingException(org.apache.distributedlog.exceptions.LockingException) DistributedLogManager(org.apache.distributedlog.api.DistributedLogManager) URI(java.net.URI) Namespace(org.apache.distributedlog.api.namespace.Namespace) Test(org.junit.Test)

Aggregations

LockingException (org.apache.distributedlog.exceptions.LockingException)13 CountDownLatch (java.util.concurrent.CountDownLatch)6 OwnershipAcquireFailedException (org.apache.distributedlog.exceptions.OwnershipAcquireFailedException)5 IOException (java.io.IOException)4 Test (org.junit.Test)4 UnexpectedException (org.apache.distributedlog.exceptions.UnexpectedException)3 ZKException (org.apache.distributedlog.exceptions.ZKException)3 URI (java.net.URI)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 DistributedLogManager (org.apache.distributedlog.api.DistributedLogManager)2 Namespace (org.apache.distributedlog.api.namespace.Namespace)2 DynamicDistributedLogConfiguration (org.apache.distributedlog.config.DynamicDistributedLogConfiguration)2 DLInterruptedException (org.apache.distributedlog.exceptions.DLInterruptedException)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Stopwatch (com.google.common.base.Stopwatch)1 Closeable (java.io.Closeable)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 List (java.util.List)1 CompletionStage (java.util.concurrent.CompletionStage)1