Search in sources :

Example 6 with UnexpectedException

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

the class TestFederatedZKLogMetadataStore method testDuplicatedLogs.

@Test(timeout = 60000)
public void testDuplicatedLogs() throws Exception {
    DistributedLogConfiguration conf = new DistributedLogConfiguration();
    conf.addConfiguration(baseConf);
    String logName = "test-log";
    FutureUtils.result(metadataStore.createLog(logName));
    URI subNs1 = FutureUtils.result(metadataStore.createSubNamespace());
    URI subNs2 = FutureUtils.result(metadataStore.createSubNamespace());
    String duplicatedLogName = "test-duplicated-logs";
    // Create same log in different sub namespaces
    metadataStore.createLogInNamespaceSync(subNs1, duplicatedLogName);
    metadataStore.createLogInNamespaceSync(subNs2, duplicatedLogName);
    try {
        FutureUtils.result(metadataStore.createLog("non-existent-log"));
        fail("should throw exception when duplicated log found");
    } catch (UnexpectedException ue) {
        // should throw unexpected exception
        assertTrue(metadataStore.duplicatedLogFound.get());
    }
    try {
        FutureUtils.result(metadataStore.getLogLocation(logName));
        fail("should throw exception when duplicated log found");
    } catch (UnexpectedException ue) {
        // should throw unexpected exception
        assertTrue(metadataStore.duplicatedLogFound.get());
    }
    try {
        FutureUtils.result(metadataStore.getLogLocation("non-existent-log"));
        fail("should throw exception when duplicated log found");
    } catch (UnexpectedException ue) {
        // should throw unexpected exception
        assertTrue(metadataStore.duplicatedLogFound.get());
    }
    try {
        FutureUtils.result(metadataStore.getLogLocation(duplicatedLogName));
        fail("should throw exception when duplicated log found");
    } catch (UnexpectedException ue) {
        // should throw unexpected exception
        assertTrue(metadataStore.duplicatedLogFound.get());
    }
    try {
        FutureUtils.result(metadataStore.getLogs());
        fail("should throw exception when duplicated log found");
    } catch (UnexpectedException ue) {
        // should throw unexpected exception
        assertTrue(metadataStore.duplicatedLogFound.get());
    }
}
Also used : DistributedLogConfiguration(com.twitter.distributedlog.DistributedLogConfiguration) UnexpectedException(com.twitter.distributedlog.exceptions.UnexpectedException) URI(java.net.URI) Test(org.junit.Test)

Example 7 with UnexpectedException

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

the class BKDistributedLogManager method getAsyncLogReaderWithLock.

protected Future<AsyncLogReader> getAsyncLogReaderWithLock(final Optional<DLSN> fromDLSN, final Optional<String> subscriberId) {
    if (!fromDLSN.isPresent() && !subscriberId.isPresent()) {
        return Future.exception(new UnexpectedException("Neither from dlsn nor subscriber id is provided."));
    }
    final BKAsyncLogReaderDLSN reader = new BKAsyncLogReaderDLSN(BKDistributedLogManager.this, scheduler, getLockStateExecutor(true), fromDLSN.isPresent() ? fromDLSN.get() : DLSN.InitialDLSN, subscriberId, false, dynConf.getDeserializeRecordSetOnReads(), statsLogger);
    pendingReaders.add(reader);
    final Future<Void> lockFuture = reader.lockStream();
    final Promise<AsyncLogReader> createPromise = new Promise<AsyncLogReader>(new Function<Throwable, BoxedUnit>() {

        @Override
        public BoxedUnit apply(Throwable cause) {
            // cancel the lock when the creation future is cancelled
            lockFuture.cancel();
            return BoxedUnit.UNIT;
        }
    });
    // lock the stream - fetch the last commit position on success
    lockFuture.flatMap(new Function<Void, Future<AsyncLogReader>>() {

        @Override
        public Future<AsyncLogReader> apply(Void complete) {
            if (fromDLSN.isPresent()) {
                return Future.value((AsyncLogReader) reader);
            }
            LOG.info("Reader {} @ {} reading last commit position from subscription store after acquired lock.", subscriberId.get(), name);
            // we acquired lock
            final SubscriptionStateStore stateStore = getSubscriptionStateStore(subscriberId.get());
            return stateStore.getLastCommitPosition().map(new ExceptionalFunction<DLSN, AsyncLogReader>() {

                @Override
                public AsyncLogReader applyE(DLSN lastCommitPosition) throws UnexpectedException {
                    LOG.info("Reader {} @ {} positioned to last commit position {}.", new Object[] { subscriberId.get(), name, lastCommitPosition });
                    reader.setStartDLSN(lastCommitPosition);
                    return reader;
                }
            });
        }
    }).addEventListener(new FutureEventListener<AsyncLogReader>() {

        @Override
        public void onSuccess(AsyncLogReader r) {
            pendingReaders.remove(reader);
            FutureUtils.setValue(createPromise, r);
        }

        @Override
        public void onFailure(final Throwable cause) {
            pendingReaders.remove(reader);
            reader.asyncClose().ensure(new AbstractFunction0<BoxedUnit>() {

                @Override
                public BoxedUnit apply() {
                    FutureUtils.setException(createPromise, cause);
                    return BoxedUnit.UNIT;
                }
            });
        }
    });
    return createPromise;
}
Also used : UnexpectedException(com.twitter.distributedlog.exceptions.UnexpectedException) SubscriptionStateStore(com.twitter.distributedlog.subscription.SubscriptionStateStore) ZKSubscriptionStateStore(com.twitter.distributedlog.subscription.ZKSubscriptionStateStore) AbstractFunction0(scala.runtime.AbstractFunction0) Promise(com.twitter.util.Promise) ExceptionalFunction(com.twitter.util.ExceptionalFunction) Function(com.twitter.util.Function) BoxedUnit(scala.runtime.BoxedUnit)

Example 8 with UnexpectedException

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

the class StreamImpl method delete.

@Override
public void delete() throws IOException {
    if (null != writer) {
        Utils.close(writer);
        synchronized (this) {
            writer = null;
            lastException = new StreamUnavailableException("Stream was deleted");
        }
    }
    if (null == manager) {
        throw new UnexpectedException("No stream " + name + " to delete");
    }
    manager.delete();
}
Also used : StreamUnavailableException(com.twitter.distributedlog.exceptions.StreamUnavailableException) UnexpectedException(com.twitter.distributedlog.exceptions.UnexpectedException)

Example 9 with UnexpectedException

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

the class ZKDistributedLock method asyncAcquire.

/**
     * Asynchronously acquire the lock. Technically the try phase of this operation--which adds us to the waiter
     * list--is executed synchronously, but the lock wait itself doesn't block.
     */
public synchronized Future<ZKDistributedLock> asyncAcquire() {
    if (null != lockAcquireFuture) {
        return Future.exception(new UnexpectedException("Someone is already acquiring/acquired lock " + lockPath));
    }
    final Promise<ZKDistributedLock> promise = new Promise<ZKDistributedLock>(new Function<Throwable, BoxedUnit>() {

        @Override
        public BoxedUnit apply(Throwable cause) {
            lockStateExecutor.submit(lockPath, new Runnable() {

                @Override
                public void run() {
                    asyncClose();
                }
            });
            return BoxedUnit.UNIT;
        }
    });
    final Stopwatch stopwatch = Stopwatch.createStarted();
    promise.addEventListener(new FutureEventListener<ZKDistributedLock>() {

        @Override
        public void onSuccess(ZKDistributedLock lock) {
            acquireStats.registerSuccessfulEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
        }

        @Override
        public void onFailure(Throwable cause) {
            acquireStats.registerFailedEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
            // release the lock if fail to acquire
            asyncClose();
        }
    });
    this.lockAcquireFuture = promise;
    lockStateExecutor.submit(lockPath, new Runnable() {

        @Override
        public void run() {
            doAsyncAcquireWithSemaphore(promise, lockTimeout);
        }
    });
    return promise;
}
Also used : Promise(com.twitter.util.Promise) UnexpectedException(com.twitter.distributedlog.exceptions.UnexpectedException) Stopwatch(com.google.common.base.Stopwatch) BoxedUnit(scala.runtime.BoxedUnit)

Example 10 with UnexpectedException

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

the class ZKSessionLock method processLockWaiters.

/**
     * Check Lock Owner Phase 2 : check all lock waiters to get current owner and wait for ownership if necessary.
     *
     * @param lockWatcher
     *          lock watcher.
     * @param wait
     *          whether to wait for ownership.
     * @param getChildrenRc
     *          result of getting all lock waiters
     * @param children
     *          current lock waiters.
     * @param promise
     *          promise to satisfy with current lock owner.
     */
private void processLockWaiters(final LockWatcher lockWatcher, final boolean wait, final int getChildrenRc, final List<String> children, final Promise<String> promise) {
    executeLockAction(lockWatcher.epoch, new LockAction() {

        @Override
        public void execute() {
            if (!lockState.inState(State.PREPARED)) {
                // e.g. lock closed or session expired after prepared
                promise.setException(new LockStateChangedException(lockPath, lockId, State.PREPARED, lockState.getState()));
                return;
            }
            if (KeeperException.Code.OK.intValue() != getChildrenRc) {
                promise.setException(KeeperException.create(KeeperException.Code.get(getChildrenRc)));
                return;
            }
            if (children.isEmpty()) {
                LOG.error("Error, member list is empty for lock {}.", lockPath);
                promise.setException(new UnexpectedException("Empty member list for lock " + lockPath));
                return;
            }
            // sort the children
            Collections.sort(children, MEMBER_COMPARATOR);
            final String cid = currentId;
            final int memberIndex = children.indexOf(cid);
            if (LOG.isDebugEnabled()) {
                LOG.debug("{} is the number {} member in the list.", cid, memberIndex);
            }
            // If we hold the lock
            if (memberIndex == 0) {
                LOG.info("{} acquired the lock {}.", cid, lockPath);
                claimOwnership(lockWatcher.epoch);
                promise.setValue(cid);
            } else if (memberIndex > 0) {
                // we are in the member list but we didn't hold the lock
                // get ownership of current owner
                asyncParseClientID(zk, lockPath, children.get(0)).addEventListener(new FutureEventListener<Pair<String, Long>>() {

                    @Override
                    public void onSuccess(Pair<String, Long> currentOwner) {
                        watchLockOwner(lockWatcher, wait, cid, children.get(memberIndex - 1), children.get(0), currentOwner, promise);
                    }

                    @Override
                    public void onFailure(final Throwable cause) {
                        // ensure promise is satisfied in lock thread
                        executeLockAction(lockWatcher.epoch, new LockAction() {

                            @Override
                            public void execute() {
                                promise.setException(cause);
                            }

                            @Override
                            public String getActionName() {
                                return "handleFailureOnParseClientID(lockPath=" + lockPath + ")";
                            }
                        }, promise);
                    }
                });
            } else {
                LOG.error("Member {} doesn't exist in the members list {} for lock {}.", new Object[] { cid, children, lockPath });
                promise.setException(new UnexpectedException("Member " + cid + " doesn't exist in member list " + children + " for lock " + lockPath));
            }
        }

        @Override
        public String getActionName() {
            return "processLockWaiters(rc=" + getChildrenRc + ", waiters=" + children + ")";
        }
    }, promise);
}
Also used : UnexpectedException(com.twitter.distributedlog.exceptions.UnexpectedException) Pair(org.apache.commons.lang3.tuple.Pair)

Aggregations

UnexpectedException (com.twitter.distributedlog.exceptions.UnexpectedException)14 URI (java.net.URI)5 Promise (com.twitter.util.Promise)4 FutureEventListener (com.twitter.util.FutureEventListener)3 List (java.util.List)3 Stopwatch (com.google.common.base.Stopwatch)2 Future (com.twitter.util.Future)2 IOException (java.io.IOException)2 Set (java.util.Set)2 Pair (org.apache.commons.lang3.tuple.Pair)2 AsyncCallback (org.apache.zookeeper.AsyncCallback)2 Test (org.junit.Test)2 BoxedUnit (scala.runtime.BoxedUnit)2 Optional (com.google.common.base.Optional)1 DistributedLogConfiguration (com.twitter.distributedlog.DistributedLogConfiguration)1 LogSegmentMetadata (com.twitter.distributedlog.LogSegmentMetadata)1 ZooKeeperClient (com.twitter.distributedlog.ZooKeeperClient)1 DLIllegalStateException (com.twitter.distributedlog.exceptions.DLIllegalStateException)1 DLInterruptedException (com.twitter.distributedlog.exceptions.DLInterruptedException)1 StreamUnavailableException (com.twitter.distributedlog.exceptions.StreamUnavailableException)1