Search in sources :

Example 1 with LockingException

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);
            }
        }
    }
}
Also used : FlushException(org.apache.distributedlog.exceptions.FlushException) FlushException(org.apache.distributedlog.exceptions.FlushException) BKException(org.apache.bookkeeper.client.BKException) WriteException(org.apache.distributedlog.exceptions.WriteException) InvalidEnvelopedEntryException(org.apache.distributedlog.exceptions.InvalidEnvelopedEntryException) LockingException(org.apache.distributedlog.exceptions.LockingException) WriteCancelledException(org.apache.distributedlog.exceptions.WriteCancelledException) BKTransmitException(org.apache.distributedlog.exceptions.BKTransmitException) EndOfStreamException(org.apache.distributedlog.exceptions.EndOfStreamException) IOException(java.io.IOException) TransactionIdOutOfOrderException(org.apache.distributedlog.exceptions.TransactionIdOutOfOrderException) LogRecordTooLongException(org.apache.distributedlog.exceptions.LogRecordTooLongException)

Example 2 with LockingException

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;
}
Also used : Delete(org.apache.zookeeper.Op.Delete) Op(org.apache.zookeeper.Op) LockingException(org.apache.distributedlog.exceptions.LockingException) ZKException(org.apache.distributedlog.exceptions.ZKException) LogExistsException(org.apache.distributedlog.exceptions.LogExistsException) Create(org.apache.zookeeper.Op.Create) ZooKeeperConnectionException(org.apache.distributedlog.ZooKeeperClient.ZooKeeperConnectionException) DLInterruptedException(org.apache.distributedlog.exceptions.DLInterruptedException)

Example 3 with LockingException

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

Example 4 with LockingException

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

Example 5 with LockingException

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

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