Search in sources :

Example 6 with FutureEventListener

use of org.apache.bookkeeper.common.concurrent.FutureEventListener in project bookkeeper by apache.

the class FederatedZKLogMetadataStore method findSubNamespaceToCreateLog.

private void findSubNamespaceToCreateLog(final String logName, final Set<URI> uris, final CompletableFuture<URI> createPromise) {
    final List<URI> uriList = Lists.newArrayListWithExpectedSize(uris.size());
    List<CompletableFuture<Set<String>>> futureList = Lists.newArrayListWithExpectedSize(uris.size());
    for (URI uri : uris) {
        SubNamespace subNs = subNamespaces.get(uri);
        if (null == subNs) {
            createPromise.completeExceptionally(new UnexpectedException("No sub namespace " + uri + " found"));
            return;
        }
        futureList.add(subNs.getLogs());
        uriList.add(uri);
    }
    FutureUtils.collect(futureList).whenComplete(new FutureEventListener<List<Set<String>>>() {

        @Override
        public void onSuccess(List<Set<String>> resultList) {
            for (int i = resultList.size() - 1; i >= 0; i--) {
                Set<String> logs = resultList.get(i);
                if (logs.size() < maxLogsPerSubnamespace) {
                    URI uri = uriList.get(i);
                    createLogInNamespace(uri, logName, createPromise);
                    return;
                }
            }
            // All sub namespaces are full
            createSubNamespace().whenComplete(new FutureEventListener<URI>() {

                @Override
                public void onSuccess(URI uri) {
                    // the new namespace will be propagated to the namespace cache by the namespace listener
                    // so we don't need to cache it here. we could go ahead to create the stream under this
                    // namespace, as we are using sequential znode. we are mostly the first guy who create
                    // the log under this namespace.
                    createLogInNamespace(uri, logName, createPromise);
                }

                @Override
                public void onFailure(Throwable cause) {
                    createPromise.completeExceptionally(cause);
                }
            });
        }

        @Override
        public void onFailure(Throwable cause) {
            createPromise.completeExceptionally(cause);
        }
    });
}
Also used : UnexpectedException(org.apache.distributedlog.exceptions.UnexpectedException) Set(java.util.Set) URI(java.net.URI) CompletableFuture(java.util.concurrent.CompletableFuture) List(java.util.List) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener)

Example 7 with FutureEventListener

use of org.apache.bookkeeper.common.concurrent.FutureEventListener in project bookkeeper by apache.

the class ZKSessionLock method asyncTryLock.

@Override
public CompletableFuture<LockWaiter> asyncTryLock(final long timeout, final TimeUnit unit) {
    final CompletableFuture<String> result = new CompletableFuture<String>();
    final boolean wait = DistributedLogConstants.LOCK_IMMEDIATE != timeout;
    if (wait) {
        asyncTryLock(wait, result);
    } else {
        // try to check locks first
        zk.getChildren(lockPath, null, new AsyncCallback.Children2Callback() {

            @Override
            public void processResult(final int rc, String path, Object ctx, final List<String> children, Stat stat) {
                lockStateExecutor.executeOrdered(lockPath, new SafeRunnable() {

                    @Override
                    public void safeRun() {
                        if (!lockState.inState(State.INIT)) {
                            result.completeExceptionally(new LockStateChangedException(lockPath, lockId, State.INIT, lockState.getState()));
                            return;
                        }
                        if (KeeperException.Code.OK.intValue() != rc) {
                            result.completeExceptionally(KeeperException.create(KeeperException.Code.get(rc)));
                            return;
                        }
                        FailpointUtils.checkFailPointNoThrow(FailpointUtils.FailPointName.FP_LockTryAcquire);
                        Collections.sort(children, MEMBER_COMPARATOR);
                        if (children.size() > 0) {
                            asyncParseClientID(zk, lockPath, children.get(0)).whenCompleteAsync(new FutureEventListener<Pair<String, Long>>() {

                                @Override
                                public void onSuccess(Pair<String, Long> owner) {
                                    if (!checkOrClaimLockOwner(owner, result)) {
                                        acquireFuture.complete(false);
                                    }
                                }

                                @Override
                                public void onFailure(final Throwable cause) {
                                    result.completeExceptionally(cause);
                                }
                            }, lockStateExecutor.chooseThread(lockPath));
                        } else {
                            asyncTryLock(wait, result);
                        }
                    }
                });
            }
        }, null);
    }
    final CompletableFuture<Boolean> waiterAcquireFuture = FutureUtils.createFuture();
    waiterAcquireFuture.whenComplete((value, cause) -> acquireFuture.completeExceptionally(cause));
    return result.thenApply(new Function<String, LockWaiter>() {

        @Override
        public LockWaiter apply(final String currentOwner) {
            final Exception acquireException = new OwnershipAcquireFailedException(lockPath, currentOwner);
            FutureUtils.within(acquireFuture, timeout, unit, acquireException, lockStateExecutor, lockPath).whenComplete(new FutureEventListener<Boolean>() {

                @Override
                public void onSuccess(Boolean acquired) {
                    completeOrFail(acquireException);
                }

                @Override
                public void onFailure(final Throwable acquireCause) {
                    completeOrFail(acquireException);
                }

                private void completeOrFail(final Throwable acquireCause) {
                    if (isLockHeld()) {
                        waiterAcquireFuture.complete(true);
                    } else {
                        asyncUnlock().whenComplete(new FutureEventListener<Void>() {

                            @Override
                            public void onSuccess(Void value) {
                                waiterAcquireFuture.completeExceptionally(acquireCause);
                            }

                            @Override
                            public void onFailure(Throwable cause) {
                                waiterAcquireFuture.completeExceptionally(acquireCause);
                            }
                        });
                    }
                }
            });
            return new LockWaiter(lockId.getLeft(), currentOwner, waiterAcquireFuture);
        }
    });
}
Also used : AsyncCallback(org.apache.zookeeper.AsyncCallback) CompletableFuture(java.util.concurrent.CompletableFuture) Stat(org.apache.zookeeper.data.Stat) Pair(org.apache.commons.lang3.tuple.Pair) OwnershipAcquireFailedException(org.apache.distributedlog.exceptions.OwnershipAcquireFailedException) SafeRunnable(org.apache.bookkeeper.util.SafeRunnable) DLInterruptedException(org.apache.distributedlog.exceptions.DLInterruptedException) LockingException(org.apache.distributedlog.exceptions.LockingException) TimeoutException(java.util.concurrent.TimeoutException) UnexpectedException(org.apache.distributedlog.exceptions.UnexpectedException) ZKException(org.apache.distributedlog.exceptions.ZKException) KeeperException(org.apache.zookeeper.KeeperException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) OwnershipAcquireFailedException(org.apache.distributedlog.exceptions.OwnershipAcquireFailedException) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener)

Example 8 with FutureEventListener

use of org.apache.bookkeeper.common.concurrent.FutureEventListener in project bookkeeper by apache.

the class BKLogHandler method getLastLogRecordAsync.

public CompletableFuture<LogRecordWithDLSN> getLastLogRecordAsync(final boolean recover, final boolean includeEndOfStream) {
    final CompletableFuture<LogRecordWithDLSN> promise = new CompletableFuture<LogRecordWithDLSN>();
    streamMetadataStore.logExists(logMetadata.getUri(), logMetadata.getLogName()).whenComplete(new FutureEventListener<Void>() {

        @Override
        public void onSuccess(Void value) {
            readLogSegmentsFromStore(LogSegmentMetadata.DESC_COMPARATOR, LogSegmentFilter.DEFAULT_FILTER, null).whenComplete(new FutureEventListener<Versioned<List<LogSegmentMetadata>>>() {

                @Override
                public void onSuccess(Versioned<List<LogSegmentMetadata>> ledgerList) {
                    if (ledgerList.getValue().isEmpty()) {
                        promise.completeExceptionally(new LogEmptyException("Log " + getFullyQualifiedName() + " has no records"));
                        return;
                    }
                    asyncGetLastLogRecord(ledgerList.getValue().iterator(), promise, recover, false, includeEndOfStream);
                }

                @Override
                public void onFailure(Throwable cause) {
                    promise.completeExceptionally(cause);
                }
            });
        }

        @Override
        public void onFailure(Throwable cause) {
            promise.completeExceptionally(cause);
        }
    });
    return promise;
}
Also used : LogEmptyException(org.apache.distributedlog.exceptions.LogEmptyException) CompletableFuture(java.util.concurrent.CompletableFuture) Versioned(org.apache.bookkeeper.versioning.Versioned) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener) List(java.util.List)

Example 9 with FutureEventListener

use of org.apache.bookkeeper.common.concurrent.FutureEventListener in project bookkeeper by apache.

the class BKLogHandler method asyncGetFirstLogRecord.

public CompletableFuture<LogRecordWithDLSN> asyncGetFirstLogRecord() {
    final CompletableFuture<LogRecordWithDLSN> promise = new CompletableFuture<LogRecordWithDLSN>();
    streamMetadataStore.logExists(logMetadata.getUri(), logMetadata.getLogName()).whenComplete(new FutureEventListener<Void>() {

        @Override
        public void onSuccess(Void value) {
            readLogSegmentsFromStore(LogSegmentMetadata.COMPARATOR, LogSegmentFilter.DEFAULT_FILTER, null).whenComplete(new FutureEventListener<Versioned<List<LogSegmentMetadata>>>() {

                @Override
                public void onSuccess(Versioned<List<LogSegmentMetadata>> ledgerList) {
                    if (ledgerList.getValue().isEmpty()) {
                        promise.completeExceptionally(new LogEmptyException("Log " + getFullyQualifiedName() + " has no records"));
                        return;
                    }
                    CompletableFuture<LogRecordWithDLSN> firstRecord = null;
                    for (LogSegmentMetadata ledger : ledgerList.getValue()) {
                        if (!ledger.isTruncated() && (ledger.getRecordCount() > 0 || ledger.isInProgress())) {
                            firstRecord = asyncReadFirstUserRecord(ledger, DLSN.InitialDLSN);
                            break;
                        }
                    }
                    if (null != firstRecord) {
                        FutureUtils.proxyTo(firstRecord, promise);
                    } else {
                        promise.completeExceptionally(new LogEmptyException("Log " + getFullyQualifiedName() + " has no records"));
                    }
                }

                @Override
                public void onFailure(Throwable cause) {
                    promise.completeExceptionally(cause);
                }
            });
        }

        @Override
        public void onFailure(Throwable cause) {
            promise.completeExceptionally(cause);
        }
    });
    return promise;
}
Also used : LogEmptyException(org.apache.distributedlog.exceptions.LogEmptyException) CompletableFuture(java.util.concurrent.CompletableFuture) Versioned(org.apache.bookkeeper.versioning.Versioned) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener) List(java.util.List)

Example 10 with FutureEventListener

use of org.apache.bookkeeper.common.concurrent.FutureEventListener in project bookkeeper by apache.

the class ReadUtils method getLogRecordNotLessThanTxId.

// 
// Search Functions
// 
/**
 * Get the log record whose transaction id is not less than provided <code>transactionId</code>.
 *
 * <p>
 * It uses a binary-search like algorithm to find the log record whose transaction id is not less than
 * provided <code>transactionId</code> within a log <code>segment</code>. You could think of a log segment
 * in terms of a sequence of records whose transaction ids are non-decreasing.
 *
 * - The sequence of records within a log segment is divided into N pieces.
 * - Find the piece of records that contains a record whose transaction id is not less than provided
 *   <code>transactionId</code>.
 *
 * N could be chosen based on trading off concurrency and latency.
 * </p>
 *
 * @param logName
 *          name of the log
 * @param segment
 *          metadata of the log segment
 * @param transactionId
 *          transaction id
 * @param executorService
 *          executor service used for processing entries
 * @param entryStore
 *          log segment entry store
 * @param nWays
 *          how many number of entries to search in parallel
 * @return found log record. none if all transaction ids are less than provided <code>transactionId</code>.
 */
public static CompletableFuture<Optional<LogRecordWithDLSN>> getLogRecordNotLessThanTxId(final String logName, final LogSegmentMetadata segment, final long transactionId, final ExecutorService executorService, final LogSegmentEntryStore entryStore, final int nWays) {
    if (!segment.isInProgress()) {
        if (segment.getLastTxId() < transactionId) {
            // all log records whose transaction id is less than provided transactionId
            // then return none
            Optional<LogRecordWithDLSN> noneRecord = Optional.absent();
            return FutureUtils.value(noneRecord);
        }
    }
    final CompletableFuture<Optional<LogRecordWithDLSN>> promise = new CompletableFuture<Optional<LogRecordWithDLSN>>();
    final FutureEventListener<LogSegmentRandomAccessEntryReader> openReaderListener = new FutureEventListener<LogSegmentRandomAccessEntryReader>() {

        @Override
        public void onSuccess(final LogSegmentRandomAccessEntryReader reader) {
            promise.whenComplete((value, cause) -> reader.asyncClose());
            long lastEntryId = reader.getLastAddConfirmed();
            if (lastEntryId < 0) {
                // it means that the log segment is created but not written yet or an empty log segment.
                // it is equivalent to 'all log records whose transaction id is less than provided transactionId'
                Optional<LogRecordWithDLSN> nonRecord = Optional.absent();
                promise.complete(nonRecord);
                return;
            }
            // all log records whose transaction id is not less than provided transactionId
            if (segment.getFirstTxId() >= transactionId) {
                final FirstTxIdNotLessThanSelector selector = new FirstTxIdNotLessThanSelector(transactionId);
                asyncReadRecordFromEntries(logName, reader, segment, executorService, new SingleEntryScanContext(0L), selector).whenComplete(new FutureEventListener<LogRecordWithDLSN>() {

                    @Override
                    public void onSuccess(LogRecordWithDLSN value) {
                        promise.complete(Optional.of(selector.result()));
                    }

                    @Override
                    public void onFailure(Throwable cause) {
                        promise.completeExceptionally(cause);
                    }
                });
                return;
            }
            getLogRecordNotLessThanTxIdFromEntries(logName, segment, transactionId, executorService, reader, Lists.newArrayList(0L, lastEntryId), nWays, Optional.<LogRecordWithDLSN>absent(), promise);
        }

        @Override
        public void onFailure(final Throwable cause) {
            promise.completeExceptionally(cause);
        }
    };
    entryStore.openRandomAccessReader(segment, false).whenCompleteAsync(openReaderListener, executorService);
    return promise;
}
Also used : Optional(com.google.common.base.Optional) LogSegmentRandomAccessEntryReader(org.apache.distributedlog.logsegment.LogSegmentRandomAccessEntryReader) FirstTxIdNotLessThanSelector(org.apache.distributedlog.selector.FirstTxIdNotLessThanSelector) CompletableFuture(java.util.concurrent.CompletableFuture) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener)

Aggregations

FutureEventListener (org.apache.bookkeeper.common.concurrent.FutureEventListener)10 CompletableFuture (java.util.concurrent.CompletableFuture)8 List (java.util.List)5 IOException (java.io.IOException)2 Set (java.util.Set)2 LedgerHandle (org.apache.bookkeeper.client.LedgerHandle)2 Versioned (org.apache.bookkeeper.versioning.Versioned)2 DLInterruptedException (org.apache.distributedlog.exceptions.DLInterruptedException)2 LogEmptyException (org.apache.distributedlog.exceptions.LogEmptyException)2 UnexpectedException (org.apache.distributedlog.exceptions.UnexpectedException)2 FirstTxIdNotLessThanSelector (org.apache.distributedlog.selector.FirstTxIdNotLessThanSelector)2 AsyncCallback (org.apache.zookeeper.AsyncCallback)2 Stat (org.apache.zookeeper.data.Stat)2 Optional (com.google.common.base.Optional)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 URI (java.net.URI)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 LinkedList (java.util.LinkedList)1 CountDownLatch (java.util.concurrent.CountDownLatch)1