Search in sources :

Example 31 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

the class BKLogHandler method asyncGetLedgerListWithRetries.

protected Future<List<LogSegmentMetadata>> asyncGetLedgerListWithRetries(Comparator<LogSegmentMetadata> comparator, LogSegmentFilter segmentFilter, Watcher watcher) {
    final Promise<List<LogSegmentMetadata>> promise = new Promise<List<LogSegmentMetadata>>();
    asyncGetLedgerListWithRetries(comparator, segmentFilter, watcher, new GenericCallback<List<LogSegmentMetadata>>() {

        @Override
        public void operationComplete(int rc, List<LogSegmentMetadata> segments) {
            if (KeeperException.Code.OK.intValue() == rc) {
                promise.setValue(segments);
            } else if (KeeperException.Code.NONODE.intValue() == rc) {
                promise.setException(new LogNotFoundException("Log " + getFullyQualifiedName() + " not found"));
            } else {
                String errMsg = "ZK Exception " + rc + " reading ledger list for " + getFullyQualifiedName();
                promise.setException(new ZKException(errMsg, KeeperException.Code.get(rc)));
            }
        }
    });
    return promise;
}
Also used : Promise(com.twitter.util.Promise) ZKException(com.twitter.distributedlog.exceptions.ZKException) List(java.util.List) ArrayList(java.util.ArrayList) LogNotFoundException(com.twitter.distributedlog.exceptions.LogNotFoundException)

Example 32 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

the class BKLogHandler method asyncForceGetLedgerList.

protected Future<List<LogSegmentMetadata>> asyncForceGetLedgerList(final Comparator<LogSegmentMetadata> comparator, final LogSegmentFilter segmentFilter, final boolean throwOnEmpty) {
    final Promise<List<LogSegmentMetadata>> promise = new Promise<List<LogSegmentMetadata>>();
    final Stopwatch stopwatch = Stopwatch.createStarted();
    asyncGetLedgerListWithRetries(comparator, segmentFilter, null).addEventListener(new FutureEventListener<List<LogSegmentMetadata>>() {

        @Override
        public void onSuccess(List<LogSegmentMetadata> ledgers) {
            forceGetListStat.registerSuccessfulEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
            if (ledgers.isEmpty() && throwOnEmpty) {
                promise.setException(new LogEmptyException("Log " + getFullyQualifiedName() + " is empty"));
            } else {
                promise.setValue(ledgers);
            }
        }

        @Override
        public void onFailure(Throwable cause) {
            forceGetListStat.registerFailedEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
            promise.setException(cause);
        }
    });
    return promise;
}
Also used : Promise(com.twitter.util.Promise) LogEmptyException(com.twitter.distributedlog.exceptions.LogEmptyException) Stopwatch(com.google.common.base.Stopwatch) List(java.util.List) ArrayList(java.util.ArrayList)

Example 33 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

the class BookKeeperClient method createLedger.

// Util functions
public Future<LedgerHandle> createLedger(int ensembleSize, int writeQuorumSize, int ackQuorumSize) {
    BookKeeper bk;
    try {
        bk = get();
    } catch (IOException ioe) {
        return Future.exception(ioe);
    }
    final Promise<LedgerHandle> promise = new Promise<LedgerHandle>();
    bk.asyncCreateLedger(ensembleSize, writeQuorumSize, ackQuorumSize, BookKeeper.DigestType.CRC32, passwd, new AsyncCallback.CreateCallback() {

        @Override
        public void createComplete(int rc, LedgerHandle lh, Object ctx) {
            if (BKException.Code.OK == rc) {
                promise.updateIfEmpty(new Return<LedgerHandle>(lh));
            } else {
                promise.updateIfEmpty(new Throw<LedgerHandle>(BKException.create(rc)));
            }
        }
    }, null);
    return promise;
}
Also used : Promise(com.twitter.util.Promise) Return(com.twitter.util.Return) LedgerHandle(org.apache.bookkeeper.client.LedgerHandle) Throw(com.twitter.util.Throw) AsyncCallback(org.apache.bookkeeper.client.AsyncCallback) BookKeeper(org.apache.bookkeeper.client.BookKeeper) IOException(java.io.IOException)

Example 34 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

the class LedgerHandleCache method asyncOpenLedger.

/**
     * Open the log segment.
     *
     * @param metadata
     *          the log segment metadata
     * @param fence
     *          whether to fence the log segment during open
     * @return a future presenting the open result.
     */
public Future<LedgerDescriptor> asyncOpenLedger(LogSegmentMetadata metadata, boolean fence) {
    final Stopwatch stopwatch = Stopwatch.createStarted();
    final OpStatsLogger openStatsLogger = fence ? openStats : openNoRecoveryStats;
    final Promise<LedgerDescriptor> promise = new Promise<LedgerDescriptor>();
    final LedgerDescriptor ledgerDesc = new LedgerDescriptor(metadata.getLedgerId(), metadata.getLogSegmentSequenceNumber(), fence);
    RefCountedLedgerHandle refhandle = handlesMap.get(ledgerDesc);
    if (null == refhandle) {
        asyncOpenLedger(ledgerDesc, new AsyncCallback.OpenCallback() {

            @Override
            public void openComplete(int rc, LedgerHandle lh, Object ctx) {
                if (BKException.Code.OK != rc) {
                    promise.setException(BKException.create(rc));
                    return;
                }
                RefCountedLedgerHandle newRefHandle = new RefCountedLedgerHandle(lh);
                RefCountedLedgerHandle oldRefHandle = handlesMap.putIfAbsent(ledgerDesc, newRefHandle);
                if (null != oldRefHandle) {
                    oldRefHandle.addRef();
                    if (newRefHandle.removeRef()) {
                        newRefHandle.handle.asyncClose(new AsyncCallback.CloseCallback() {

                            @Override
                            public void closeComplete(int i, LedgerHandle ledgerHandle, Object o) {
                            // No action necessary
                            }
                        }, null);
                    }
                }
                promise.setValue(ledgerDesc);
            }
        }, null);
    } else {
        refhandle.addRef();
        promise.setValue(ledgerDesc);
    }
    return promise.addEventListener(new FutureEventListener<LedgerDescriptor>() {

        @Override
        public void onSuccess(LedgerDescriptor value) {
            openStatsLogger.registerSuccessfulEvent(stopwatch.elapsed(TimeUnit.MICROSECONDS));
        }

        @Override
        public void onFailure(Throwable cause) {
            openStatsLogger.registerFailedEvent(stopwatch.elapsed(TimeUnit.MICROSECONDS));
        }
    });
}
Also used : LedgerHandle(org.apache.bookkeeper.client.LedgerHandle) AsyncCallback(org.apache.bookkeeper.client.AsyncCallback) Stopwatch(com.google.common.base.Stopwatch) Promise(com.twitter.util.Promise) OpStatsLogger(org.apache.bookkeeper.stats.OpStatsLogger)

Example 35 with Promise

use of com.twitter.util.Promise in project distributedlog by twitter.

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 handleCache
     *          ledger handle cache
     * @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 Future<Optional<LogRecordWithDLSN>> getLogRecordNotLessThanTxId(final String logName, final LogSegmentMetadata segment, final long transactionId, final ExecutorService executorService, final LedgerHandleCache handleCache, 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 Future.value(noneRecord);
        }
    }
    final Promise<Optional<LogRecordWithDLSN>> promise = new Promise<Optional<LogRecordWithDLSN>>();
    final FutureEventListener<LedgerDescriptor> openLedgerListener = new FutureEventListener<LedgerDescriptor>() {

        @Override
        public void onSuccess(final LedgerDescriptor ld) {
            promise.ensure(new AbstractFunction0<BoxedUnit>() {

                @Override
                public BoxedUnit apply() {
                    handleCache.asyncCloseLedger(ld);
                    return BoxedUnit.UNIT;
                }
            });
            long lastEntryId;
            try {
                lastEntryId = handleCache.getLastAddConfirmed(ld);
            } catch (BKException e) {
                promise.setException(e);
                return;
            }
            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.setValue(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, ld, handleCache, segment, executorService, new SingleEntryScanContext(0L), selector).addEventListener(new FutureEventListener<LogRecordWithDLSN>() {

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

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

        @Override
        public void onFailure(final Throwable cause) {
            String errMsg = "Error opening log segment [" + segment + "] for find record from " + logName;
            promise.setException(new IOException(errMsg, BKException.create(FutureUtils.bkResultCode(cause))));
        }
    };
    handleCache.asyncOpenLedger(segment, false).addEventListener(FutureEventListenerRunnable.of(openLedgerListener, executorService));
    return promise;
}
Also used : Optional(com.google.common.base.Optional) IOException(java.io.IOException) FirstTxIdNotLessThanSelector(com.twitter.distributedlog.selector.FirstTxIdNotLessThanSelector) Promise(com.twitter.util.Promise) FutureEventListener(com.twitter.util.FutureEventListener) BKException(org.apache.bookkeeper.client.BKException) BoxedUnit(scala.runtime.BoxedUnit)

Aggregations

Promise (com.twitter.util.Promise)48 IOException (java.io.IOException)11 Stat (org.apache.zookeeper.data.Stat)11 Test (org.junit.Test)10 FutureEventListener (com.twitter.util.FutureEventListener)9 ZkVersion (org.apache.bookkeeper.meta.ZkVersion)9 BoxedUnit (scala.runtime.BoxedUnit)9 ZKException (com.twitter.distributedlog.exceptions.ZKException)8 Future (com.twitter.util.Future)8 Versioned (org.apache.bookkeeper.versioning.Versioned)8 Stopwatch (com.google.common.base.Stopwatch)7 UnexpectedException (com.twitter.distributedlog.exceptions.UnexpectedException)7 List (java.util.List)7 AsyncCallback (org.apache.zookeeper.AsyncCallback)7 DLInterruptedException (com.twitter.distributedlog.exceptions.DLInterruptedException)6 Transaction (com.twitter.distributedlog.util.Transaction)6 Version (org.apache.bookkeeper.versioning.Version)6 KeeperException (org.apache.zookeeper.KeeperException)6 ByteBuffer (java.nio.ByteBuffer)5 ArrayList (java.util.ArrayList)5