Search in sources :

Example 6 with FutureEventListener

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

the class ReadUtils method asyncReadRecordFromEntries.

/**
 * Read record from a given range of ledger entries.
 *
 * @param streamName
 *          fully qualified stream name (used for logging)
 * @param ledgerDescriptor
 *          ledger descriptor.
 * @param handleCache
 *          ledger handle cache.
 * @param executorService
 *          executor service used for processing entries
 * @param context
 *          scan context
 * @return a future with the log record.
 */
private static Future<LogRecordWithDLSN> asyncReadRecordFromEntries(final String streamName, final LedgerDescriptor ledgerDescriptor, LedgerHandleCache handleCache, final LogSegmentMetadata metadata, final ExecutorService executorService, final ScanContext context, final LogRecordSelector selector) {
    final Promise<LogRecordWithDLSN> promise = new Promise<LogRecordWithDLSN>();
    final long startEntryId = context.curStartEntryId.get();
    final long endEntryId = context.curEndEntryId.get();
    if (LOG.isDebugEnabled()) {
        LOG.debug("{} reading entries [{} - {}] from {}.", new Object[] { streamName, startEntryId, endEntryId, ledgerDescriptor });
    }
    FutureEventListener<Enumeration<LedgerEntry>> readEntriesListener = new FutureEventListener<Enumeration<LedgerEntry>>() {

        @Override
        public void onSuccess(final Enumeration<LedgerEntry> entries) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("{} finished reading entries [{} - {}] from {}", new Object[] { streamName, startEntryId, endEntryId, ledgerDescriptor });
            }
            LogRecordWithDLSN record = null;
            while (entries.hasMoreElements()) {
                LedgerEntry entry = entries.nextElement();
                try {
                    visitEntryRecords(streamName, metadata, ledgerDescriptor.getLogSegmentSequenceNo(), entry, context, selector);
                } catch (IOException ioe) {
                    // exception is only thrown due to bad ledger entry, so it might be corrupted
                    // we shouldn't do anything beyond this point. throw the exception to application
                    promise.setException(ioe);
                    return;
                }
            }
            record = selector.result();
            if (LOG.isDebugEnabled()) {
                LOG.debug("{} got record from entries [{} - {}] of {} : {}", new Object[] { streamName, startEntryId, endEntryId, ledgerDescriptor, record });
            }
            promise.setValue(record);
        }

        @Override
        public void onFailure(final Throwable cause) {
            String errMsg = "Error reading entries [" + startEntryId + "-" + endEntryId + "] for reading record of " + streamName;
            promise.setException(new IOException(errMsg, BKException.create(FutureUtils.bkResultCode(cause))));
        }
    };
    handleCache.asyncReadEntries(ledgerDescriptor, startEntryId, endEntryId).addEventListener(FutureEventListenerRunnable.of(readEntriesListener, executorService));
    return promise;
}
Also used : Promise(com.twitter.util.Promise) Enumeration(java.util.Enumeration) LedgerEntry(org.apache.bookkeeper.client.LedgerEntry) FutureEventListener(com.twitter.util.FutureEventListener) IOException(java.io.IOException)

Example 7 with FutureEventListener

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

the class ProxyClientManager method createClient.

/**
 * Create a client to proxy <code>address</code>.
 *
 * @param address
 *          proxy address
 * @return proxy client
 */
public ProxyClient createClient(final SocketAddress address) {
    final ProxyClient sc = clientBuilder.build(address);
    ProxyClient oldSC = address2Services.putIfAbsent(address, sc);
    if (null != oldSC) {
        sc.close();
        return oldSC;
    } else {
        final Stopwatch stopwatch = Stopwatch.createStarted();
        FutureEventListener<ServerInfo> listener = new FutureEventListener<ServerInfo>() {

            @Override
            public void onSuccess(ServerInfo serverInfo) {
                notifyHandshakeSuccess(address, sc, serverInfo, true, stopwatch);
            }

            @Override
            public void onFailure(Throwable cause) {
                notifyHandshakeFailure(address, sc, cause, stopwatch);
            }
        };
        // send a ping messaging after creating connections.
        handshake(address, sc, listener, true, true);
        return sc;
    }
}
Also used : ServerInfo(com.twitter.distributedlog.thrift.service.ServerInfo) Stopwatch(com.google.common.base.Stopwatch) FutureEventListener(com.twitter.util.FutureEventListener)

Example 8 with FutureEventListener

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

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<Future<ZKDistributedLock>> results = new ArrayList<Future<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().addEventListener(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);
        Await.result(results.get(i));
        FutureUtils.result(lockArray[i].asyncClose());
    }
}
Also used : ArrayList(java.util.ArrayList) Future(com.twitter.util.Future) FutureEventListener(com.twitter.util.FutureEventListener) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 9 with FutureEventListener

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

the class LedgerAllocatorPool method tryObtain.

@Override
public Future<LedgerHandle> tryObtain(final Transaction<Object> txn, final Transaction.OpListener<LedgerHandle> listener) {
    final SimpleLedgerAllocator allocator;
    synchronized (this) {
        if (allocatingList.isEmpty()) {
            return Future.exception(new IOException("No ledger allocator available under " + poolPath + "."));
        } else {
            allocator = allocatingList.removeFirst();
        }
    }
    final Promise<LedgerHandle> tryObtainPromise = new Promise<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.setValue(lh);
            }
        }

        @Override
        public void onFailure(Throwable cause) {
            try {
                rescueAllocator(allocator);
            } catch (IOException ioe) {
                logger.info("Failed to rescue allocator {}", allocator.allocatePath, ioe);
            }
            tryObtainPromise.setException(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);
        }
    }).addEventListener(tryObtainListener);
    return tryObtainPromise;
}
Also used : Promise(com.twitter.util.Promise) LedgerHandle(org.apache.bookkeeper.client.LedgerHandle) FutureEventListener(com.twitter.util.FutureEventListener) IOException(java.io.IOException)

Example 10 with FutureEventListener

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

the class ZKSessionLock method asyncTryLock.

@Override
public Future<LockWaiter> asyncTryLock(final long timeout, final TimeUnit unit) {
    final Promise<String> result = new Promise<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.submit(lockPath, new SafeRunnable() {

                    @Override
                    public void safeRun() {
                        if (!lockState.inState(State.INIT)) {
                            result.setException(new LockStateChangedException(lockPath, lockId, State.INIT, lockState.getState()));
                            return;
                        }
                        if (KeeperException.Code.OK.intValue() != rc) {
                            result.setException(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)).addEventListener(new FutureEventListener<Pair<String, Long>>() {

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

                                @Override
                                public void onFailure(final Throwable cause) {
                                    lockStateExecutor.submit(lockPath, new SafeRunnable() {

                                        @Override
                                        public void safeRun() {
                                            result.setException(cause);
                                        }
                                    });
                                }
                            });
                        } else {
                            asyncTryLock(wait, result);
                        }
                    }
                });
            }
        }, null);
    }
    final Promise<Boolean> waiterAcquireFuture = new Promise<Boolean>(new com.twitter.util.Function<Throwable, BoxedUnit>() {

        @Override
        public BoxedUnit apply(Throwable t) {
            acquireFuture.raise(t);
            return BoxedUnit.UNIT;
        }
    });
    return result.map(new AbstractFunction1<String, LockWaiter>() {

        @Override
        public LockWaiter apply(final String currentOwner) {
            final Exception acquireException = new OwnershipAcquireFailedException(lockPath, currentOwner);
            FutureUtils.within(acquireFuture, timeout, unit, acquireException, lockStateExecutor, lockPath).addEventListener(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.setValue(true);
                    } else {
                        asyncUnlock().addEventListener(new FutureEventListener<BoxedUnit>() {

                            @Override
                            public void onSuccess(BoxedUnit value) {
                                waiterAcquireFuture.setException(acquireCause);
                            }

                            @Override
                            public void onFailure(Throwable cause) {
                                waiterAcquireFuture.setException(acquireCause);
                            }
                        });
                    }
                }
            });
            ;
            return new LockWaiter(lockId.getLeft(), currentOwner, waiterAcquireFuture);
        }
    });
}
Also used : AsyncCallback(org.apache.zookeeper.AsyncCallback) Stat(org.apache.zookeeper.data.Stat) BoxedUnit(scala.runtime.BoxedUnit) Pair(org.apache.commons.lang3.tuple.Pair) OwnershipAcquireFailedException(com.twitter.distributedlog.exceptions.OwnershipAcquireFailedException) Return(com.twitter.util.Return) SafeRunnable(org.apache.bookkeeper.util.SafeRunnable) 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) Promise(com.twitter.util.Promise) FutureEventListener(com.twitter.util.FutureEventListener)

Aggregations

FutureEventListener (com.twitter.util.FutureEventListener)23 Promise (com.twitter.util.Promise)9 IOException (java.io.IOException)6 List (java.util.List)6 Future (com.twitter.util.Future)5 Stopwatch (com.google.common.base.Stopwatch)4 UnexpectedException (com.twitter.distributedlog.exceptions.UnexpectedException)4 ArrayList (java.util.ArrayList)4 BoxedUnit (scala.runtime.BoxedUnit)4 DLInterruptedException (com.twitter.distributedlog.exceptions.DLInterruptedException)3 LogEmptyException (com.twitter.distributedlog.exceptions.LogEmptyException)3 Set (java.util.Set)3 CountDownLatch (java.util.concurrent.CountDownLatch)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 LockingException (com.twitter.distributedlog.exceptions.LockingException)2 OwnershipAcquireFailedException (com.twitter.distributedlog.exceptions.OwnershipAcquireFailedException)2 ZKException (com.twitter.distributedlog.exceptions.ZKException)2 FirstTxIdNotLessThanSelector (com.twitter.distributedlog.selector.FirstTxIdNotLessThanSelector)2 ZKTransaction (com.twitter.distributedlog.zk.ZKTransaction)2 HashSet (java.util.HashSet)2