Search in sources :

Example 1 with FutureEventListener

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

the class ReadUtils method getLogRecordNotLessThanTxIdFromEntries.

/**
 * Find the log record whose transaction id is not less than provided <code>transactionId</code> from
 * entries between <code>startEntryId</code> and <code>endEntryId</code>.
 *
 * @param logName
 *          name of the log
 * @param segment
 *          log segment
 * @param transactionId
 *          provided transaction id to search
 * @param executorService
 *          executor service
 * @param reader
 *          log segment random access reader
 * @param entriesToSearch
 *          list of entries to search
 * @param nWays
 *          how many entries to search in parallel
 * @param prevFoundRecord
 *          the log record found in previous search
 * @param promise
 *          promise to satisfy the result
 */
private static void getLogRecordNotLessThanTxIdFromEntries(final String logName, final LogSegmentMetadata segment, final long transactionId, final ExecutorService executorService, final LogSegmentRandomAccessEntryReader reader, final List<Long> entriesToSearch, final int nWays, final Optional<LogRecordWithDLSN> prevFoundRecord, final CompletableFuture<Optional<LogRecordWithDLSN>> promise) {
    final List<CompletableFuture<LogRecordWithDLSN>> searchResults = Lists.newArrayListWithExpectedSize(entriesToSearch.size());
    for (Long entryId : entriesToSearch) {
        LogRecordSelector selector = new FirstTxIdNotLessThanSelector(transactionId);
        CompletableFuture<LogRecordWithDLSN> searchResult = asyncReadRecordFromEntries(logName, reader, segment, executorService, new SingleEntryScanContext(entryId), selector);
        searchResults.add(searchResult);
    }
    FutureEventListener<List<LogRecordWithDLSN>> processSearchResultsListener = new FutureEventListener<List<LogRecordWithDLSN>>() {

        @Override
        public void onSuccess(List<LogRecordWithDLSN> resultList) {
            processSearchResults(logName, segment, transactionId, executorService, reader, resultList, nWays, prevFoundRecord, promise);
        }

        @Override
        public void onFailure(Throwable cause) {
            promise.completeExceptionally(cause);
        }
    };
    FutureUtils.collect(searchResults).whenCompleteAsync(processSearchResultsListener, executorService);
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) AtomicLong(java.util.concurrent.atomic.AtomicLong) LogRecordSelector(org.apache.distributedlog.selector.LogRecordSelector) List(java.util.List) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener) FirstTxIdNotLessThanSelector(org.apache.distributedlog.selector.FirstTxIdNotLessThanSelector)

Example 2 with FutureEventListener

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

the class LedgerAllocatorPool method tryObtain.

@Override
public CompletableFuture<LedgerHandle> tryObtain(final Transaction<Object> txn, final Transaction.OpListener<LedgerHandle> listener) {
    final SimpleLedgerAllocator allocator;
    synchronized (this) {
        if (allocatingList.isEmpty()) {
            return FutureUtils.exception(new IOException("No ledger allocator available under " + poolPath + "."));
        } else {
            allocator = allocatingList.removeFirst();
        }
    }
    final CompletableFuture<LedgerHandle> tryObtainPromise = new CompletableFuture<LedgerHandle>();
    final FutureEventListener<LedgerHandle> tryObtainListener = new FutureEventListener<LedgerHandle>() {

        @Override
        public void onSuccess(LedgerHandle lh) {
            synchronized (LedgerAllocatorPool.this) {
                obtainMap.put(lh, allocator);
                reverseObtainMap.put(allocator, lh);
                tryObtainPromise.complete(lh);
            }
        }

        @Override
        public void onFailure(Throwable cause) {
            try {
                rescueAllocator(allocator);
            } catch (IOException ioe) {
                logger.info("Failed to rescue allocator {}", allocator.allocatePath, ioe);
            }
            tryObtainPromise.completeExceptionally(cause);
        }
    };
    allocator.tryObtain(txn, new Transaction.OpListener<LedgerHandle>() {

        @Override
        public void onCommit(LedgerHandle lh) {
            confirmObtain(allocator);
            listener.onCommit(lh);
        }

        @Override
        public void onAbort(Throwable t) {
            abortObtain(allocator);
            listener.onAbort(t);
        }
    }).whenComplete(tryObtainListener);
    return tryObtainPromise;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) LedgerHandle(org.apache.bookkeeper.client.LedgerHandle) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener) IOException(java.io.IOException)

Example 3 with FutureEventListener

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

the class SimpleLedgerAllocator method cleanupAndClose.

private void cleanupAndClose(final CompletableFuture<Void> closePromise) {
    LOG.info("Closing ledger allocator on {}.", allocatePath);
    final ZKTransaction txn = new ZKTransaction(zkc);
    // try obtain ledger handle
    tryObtain(txn, new OpListener<LedgerHandle>() {

        @Override
        public void onCommit(LedgerHandle r) {
            // no-op
            complete();
        }

        @Override
        public void onAbort(Throwable t) {
            // no-op
            complete();
        }

        private void complete() {
            closePromise.complete(null);
            LOG.info("Closed ledger allocator on {}.", allocatePath);
        }
    }).whenComplete(new FutureEventListener<LedgerHandle>() {

        @Override
        public void onSuccess(LedgerHandle lh) {
            // try obtain succeed
            // if we could obtain the ledger handle, we have the responsibility to close it
            deleteLedger(lh.getId());
            // wait for deletion to be completed
            List<CompletableFuture<Void>> outstandingDeletions;
            synchronized (ledgerDeletions) {
                outstandingDeletions = Lists.newArrayList(ledgerDeletions);
            }
            FutureUtils.collect(outstandingDeletions).whenComplete(new FutureEventListener<List<Void>>() {

                @Override
                public void onSuccess(List<Void> values) {
                    txn.execute();
                }

                @Override
                public void onFailure(Throwable cause) {
                    LOG.debug("Fail to obtain the allocated ledger handle when closing the allocator : ", cause);
                    closePromise.complete(null);
                }
            });
        }

        @Override
        public void onFailure(Throwable cause) {
            LOG.debug("Fail to obtain the allocated ledger handle when closing the allocator : ", cause);
            closePromise.complete(null);
        }
    });
}
Also used : OpListener(org.apache.distributedlog.util.Transaction.OpListener) LedgerHandle(org.apache.bookkeeper.client.LedgerHandle) LinkedList(java.util.LinkedList) List(java.util.List) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener) ZKTransaction(org.apache.distributedlog.zk.ZKTransaction)

Example 4 with FutureEventListener

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

the class ZKAccessControlManager method fetchAccessControlEntries.

private void fetchAccessControlEntries(final CompletableFuture<Void> promise) {
    try {
        zkc.get().getChildren(zkRootPath, this, new AsyncCallback.Children2Callback() {

            @Override
            public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
                if (KeeperException.Code.OK.intValue() != rc) {
                    promise.completeExceptionally(KeeperException.create(KeeperException.Code.get(rc)));
                    return;
                }
                Set<String> streamsReceived = new HashSet<String>();
                streamsReceived.addAll(children);
                Set<String> streamsCached = streamEntries.keySet();
                Set<String> streamsRemoved = Sets.difference(streamsCached, streamsReceived).immutableCopy();
                for (String s : streamsRemoved) {
                    ZKAccessControl accessControl = streamEntries.remove(s);
                    if (null != accessControl) {
                        logger.info("Removed Access Control Entry for stream {} : {}", s, accessControl.getAccessControlEntry());
                    }
                }
                if (streamsReceived.isEmpty()) {
                    promise.complete(null);
                    return;
                }
                final AtomicInteger numPendings = new AtomicInteger(streamsReceived.size());
                final AtomicInteger numFailures = new AtomicInteger(0);
                for (String s : streamsReceived) {
                    final String streamName = s;
                    ZKAccessControl.read(zkc, zkRootPath + "/" + streamName, null).whenComplete(new FutureEventListener<ZKAccessControl>() {

                        @Override
                        public void onSuccess(ZKAccessControl accessControl) {
                            streamEntries.put(streamName, accessControl);
                            logger.info("Added overrided access control for stream {} : {}", streamName, accessControl.getAccessControlEntry());
                            complete();
                        }

                        @Override
                        public void onFailure(Throwable cause) {
                            if (cause instanceof KeeperException.NoNodeException) {
                                streamEntries.remove(streamName);
                            } else if (cause instanceof ZKAccessControl.CorruptedAccessControlException) {
                                logger.warn("Access control is corrupted for stream {} @ {},skipped it ...", new Object[] { streamName, zkRootPath, cause });
                                streamEntries.remove(streamName);
                            } else {
                                if (1 == numFailures.incrementAndGet()) {
                                    promise.completeExceptionally(cause);
                                }
                            }
                            complete();
                        }

                        private void complete() {
                            if (0 == numPendings.decrementAndGet() && numFailures.get() == 0) {
                                promise.complete(null);
                            }
                        }
                    });
                }
            }
        }, null);
    } catch (ZooKeeperClient.ZooKeeperConnectionException e) {
        promise.completeExceptionally(e);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        promise.completeExceptionally(e);
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) AsyncCallback(org.apache.zookeeper.AsyncCallback) DLInterruptedException(org.apache.distributedlog.exceptions.DLInterruptedException) Stat(org.apache.zookeeper.data.Stat) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ZooKeeperClient(org.apache.distributedlog.ZooKeeperClient) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener)

Example 5 with FutureEventListener

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

the class TestDistributedLock method testAsyncAcquireBasics.

@Test(timeout = 60000)
public void testAsyncAcquireBasics() throws Exception {
    TestLockFactory locks = new TestLockFactory(runtime.getMethodName(), zkc, lockStateExecutor);
    int count = 3;
    ArrayList<CompletableFuture<ZKDistributedLock>> results = new ArrayList<CompletableFuture<ZKDistributedLock>>(count);
    ZKDistributedLock[] lockArray = new ZKDistributedLock[count];
    final CountDownLatch[] latches = new CountDownLatch[count];
    // the future.
    for (int i = 0; i < count; i++) {
        latches[i] = new CountDownLatch(1);
        lockArray[i] = locks.createLock(i, zkc);
        final int index = i;
        results.add(lockArray[i].asyncAcquire().whenComplete(new FutureEventListener<ZKDistributedLock>() {

            @Override
            public void onSuccess(ZKDistributedLock lock) {
                latches[index].countDown();
            }

            @Override
            public void onFailure(Throwable cause) {
                fail("unexpected failure " + cause);
            }
        }));
    }
    // acquired).
    for (int i = 0; i < count; i++) {
        latches[i].await();
        assertLatchesSet(latches, i + 1);
        Utils.ioResult(results.get(i));
        Utils.ioResult(lockArray[i].asyncClose());
    }
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) FutureEventListener(org.apache.bookkeeper.common.concurrent.FutureEventListener) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

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