Search in sources :

Example 1 with LockingException

use of com.twitter.distributedlog.exceptions.LockingException in project distributedlog by twitter.

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);
    DistributedLogNamespace namespace = DistributedLogNamespaceBuilder.newBuilder().conf(confLocal).uri(uri).clientId("gabbagoo").build();
    DistributedLogManager dlm = namespace.openLog(name);
    DistributedLogNamespace namespace1 = DistributedLogNamespaceBuilder.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
    Await.result(writer.write(DLMTestUtil.getLogRecordInstance(txid++)));
    writer.flushAndCommit();
    BKLogSegmentWriter perStreamWriter = writer.getCachedLogWriter();
    DistributedLock lock = perStreamWriter.getLock();
    FutureUtils.result(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);
        Await.result(writer.write(DLMTestUtil.getLogRecordInstance(txid++)));
        fail("should have thrown");
    } catch (LockingException ex) {
        LOG.debug("caught exception ", ex);
    }
    writer.close();
    dlm.close();
}
Also used : DynamicDistributedLogConfiguration(com.twitter.distributedlog.config.DynamicDistributedLogConfiguration) DistributedLock(com.twitter.distributedlog.lock.DistributedLock) LockingException(com.twitter.distributedlog.exceptions.LockingException) DistributedLogNamespace(com.twitter.distributedlog.namespace.DistributedLogNamespace) URI(java.net.URI) Test(org.junit.Test)

Example 2 with LockingException

use of com.twitter.distributedlog.exceptions.LockingException in project distributedlog by twitter.

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(), 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))));
    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(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
        assertEquals(State.WAITING, lock1.getLockState());
        assertEquals(lock1.getLockId(), Await.result(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(), 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))));
        awaitState(State.WAITING, lock0_1);
        assertEquals(lock0_1.getLockId(), Await.result(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(), Await.result(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(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
        } else {
            children = getLockWaiters(zkc, lockPath);
            assertEquals(2, children.size());
            assertEquals(State.CLAIMED, lock1.getLockState());
            assertEquals(lock1.getLockId(), Await.result(asyncParseClientID(zkc.get(), lockPath, children.get(0))));
            assertEquals(State.WAITING, lock0_1.getLockState());
            assertEquals(lock0_1.getLockId(), Await.result(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(), Await.result(asyncParseClientID(zkc0.get(), lockPath, children.get(0))));
    }
}
Also used : LockingException(com.twitter.distributedlog.exceptions.LockingException) OwnershipAcquireFailedException(com.twitter.distributedlog.exceptions.OwnershipAcquireFailedException) SafeRunnable(org.apache.bookkeeper.util.SafeRunnable) ZKSessionLock(com.twitter.distributedlog.lock.ZKSessionLock) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 3 with LockingException

use of com.twitter.distributedlog.exceptions.LockingException in project distributedlog by twitter.

the class ZKDistributedLock method asyncTryLock.

void asyncTryLock(SessionLock lock, final Promise<ZKDistributedLock> acquirePromise, final long lockTimeout) {
    if (null != tryLockFuture) {
        tryLockFuture.cancel();
    }
    tryLockFuture = lock.asyncTryLock(lockTimeout, TimeUnit.MILLISECONDS);
    tryLockFuture.addEventListener(OrderedFutureEventListener.of(new FutureEventListener<LockWaiter>() {

        @Override
        public void onSuccess(LockWaiter waiter) {
            synchronized (ZKDistributedLock.this) {
                if (closed) {
                    LOG.info("Skipping acquiring lock {} since it is already closed", lockPath);
                    waiter.getAcquireFuture().raise(new LockingException(lockPath, "lock is already closed."));
                    FutureUtils.setException(acquirePromise, newLockClosedException());
                    return;
                }
            }
            tryLockFuture = null;
            lockWaiter = waiter;
            waitForAcquire(waiter, acquirePromise);
        }

        @Override
        public void onFailure(Throwable cause) {
            FutureUtils.setException(acquirePromise, cause);
        }
    }, lockStateExecutor, lockPath));
}
Also used : LockingException(com.twitter.distributedlog.exceptions.LockingException) FutureEventListener(com.twitter.util.FutureEventListener) OrderedFutureEventListener(com.twitter.distributedlog.util.FutureUtils.OrderedFutureEventListener)

Example 4 with LockingException

use of com.twitter.distributedlog.exceptions.LockingException in project distributedlog by twitter.

the class ZKSessionLock method waitForTry.

synchronized LockWaiter waitForTry(Stopwatch stopwatch, Future<LockWaiter> tryFuture) throws LockingException {
    boolean success = false;
    boolean stateChanged = false;
    LockWaiter waiter;
    try {
        waiter = Await.result(tryFuture, Duration.fromMilliseconds(lockOpTimeout));
        success = true;
    } catch (LockStateChangedException ex) {
        stateChanged = true;
        throw ex;
    } catch (LockingException ex) {
        throw ex;
    } catch (TimeoutException toe) {
        tryTimeouts.inc();
        throw new LockingException(lockPath, "Timeout during try phase of lock acquire", toe);
    } catch (Exception ex) {
        String message = getLockId() + " failed to lock " + lockPath;
        throw new LockingException(lockPath, message, ex);
    } finally {
        if (success) {
            tryStats.registerSuccessfulEvent(stopwatch.elapsed(TimeUnit.MICROSECONDS));
        } else {
            tryStats.registerFailedEvent(stopwatch.elapsed(TimeUnit.MICROSECONDS));
        }
        // Exception, i.e. an Error
        if (!success && !stateChanged) {
            unlock();
        }
    }
    return waiter;
}
Also used : LockingException(com.twitter.distributedlog.exceptions.LockingException) UnexpectedException(com.twitter.distributedlog.exceptions.UnexpectedException) ZKException(com.twitter.distributedlog.exceptions.ZKException) DLInterruptedException(com.twitter.distributedlog.exceptions.DLInterruptedException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) LockingException(com.twitter.distributedlog.exceptions.LockingException) KeeperException(org.apache.zookeeper.KeeperException) TimeoutException(com.twitter.util.TimeoutException) IOException(java.io.IOException) OwnershipAcquireFailedException(com.twitter.distributedlog.exceptions.OwnershipAcquireFailedException) TimeoutException(com.twitter.util.TimeoutException)

Example 5 with LockingException

use of com.twitter.distributedlog.exceptions.LockingException in project distributedlog by twitter.

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);
    FutureUtils.result(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, Await.result(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, Await.result(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 {
                FutureUtils.result(lock1.asyncAcquire());
                lockLatch.countDown();
            } catch (IOException 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 : IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) LockingException(com.twitter.distributedlog.exceptions.LockingException) Test(org.junit.Test)

Aggregations

LockingException (com.twitter.distributedlog.exceptions.LockingException)12 ZKSessionLock (com.twitter.distributedlog.lock.ZKSessionLock)7 CountDownLatch (java.util.concurrent.CountDownLatch)6 OwnershipAcquireFailedException (com.twitter.distributedlog.exceptions.OwnershipAcquireFailedException)5 SafeRunnable (org.apache.bookkeeper.util.SafeRunnable)5 Test (org.junit.Test)5 IOException (java.io.IOException)3 KeeperException (org.apache.zookeeper.KeeperException)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Stopwatch (com.google.common.base.Stopwatch)1 DynamicDistributedLogConfiguration (com.twitter.distributedlog.config.DynamicDistributedLogConfiguration)1 DLInterruptedException (com.twitter.distributedlog.exceptions.DLInterruptedException)1 UnexpectedException (com.twitter.distributedlog.exceptions.UnexpectedException)1 ZKException (com.twitter.distributedlog.exceptions.ZKException)1 DistributedLock (com.twitter.distributedlog.lock.DistributedLock)1 DistributedLogNamespace (com.twitter.distributedlog.namespace.DistributedLogNamespace)1 OrderedFutureEventListener (com.twitter.distributedlog.util.FutureUtils.OrderedFutureEventListener)1 FutureEventListener (com.twitter.util.FutureEventListener)1 Promise (com.twitter.util.Promise)1 TimeoutException (com.twitter.util.TimeoutException)1