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;
}
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;
}
}
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());
}
}
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;
}
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);
}
});
}
Aggregations