use of com.twitter.util.Function0 in project distributedlog by twitter.
the class BKLogSegmentWriter method addComplete.
@Override
public void addComplete(final int rc, LedgerHandle handle, final long entryId, final Object ctx) {
final AtomicReference<Integer> effectiveRC = new AtomicReference<Integer>(rc);
try {
if (FailpointUtils.checkFailPoint(FailpointUtils.FailPointName.FP_TransmitComplete)) {
effectiveRC.set(BKException.Code.UnexpectedConditionException);
}
} catch (Exception exc) {
effectiveRC.set(BKException.Code.UnexpectedConditionException);
}
// Sanity check to make sure we're receiving these callbacks in order.
if (entryId > -1 && lastEntryId >= entryId) {
LOG.error("Log segment {} saw out of order entry {} lastEntryId {}", new Object[] { fullyQualifiedLogSegment, entryId, lastEntryId });
}
lastEntryId = entryId;
assert (ctx instanceof BKTransmitPacket);
final BKTransmitPacket transmitPacket = (BKTransmitPacket) ctx;
// Time from transmit until receipt of addComplete callback
addCompleteTime.registerSuccessfulEvent(TimeUnit.MICROSECONDS.convert(System.nanoTime() - transmitPacket.getTransmitTime(), TimeUnit.NANOSECONDS));
if (BKException.Code.OK == rc) {
EntryBuffer recordSet = transmitPacket.getRecordSet();
if (recordSet.hasUserRecords()) {
synchronized (this) {
lastTxIdAcknowledged = Math.max(lastTxIdAcknowledged, recordSet.getMaxTxId());
}
}
}
if (null != addCompleteFuturePool) {
final Stopwatch queuedTime = Stopwatch.createStarted();
addCompleteFuturePool.apply(new Function0<Void>() {
public Void apply() {
final Stopwatch deferredTime = Stopwatch.createStarted();
addCompleteQueuedTime.registerSuccessfulEvent(queuedTime.elapsed(TimeUnit.MICROSECONDS));
addCompleteDeferredProcessing(transmitPacket, entryId, effectiveRC.get());
addCompleteDeferredTime.registerSuccessfulEvent(deferredTime.elapsed(TimeUnit.MICROSECONDS));
return null;
}
@Override
public String toString() {
return String.format("AddComplete(Stream=%s, entryId=%d, rc=%d)", fullyQualifiedLogSegment, entryId, rc);
}
}).addEventListener(new FutureEventListener<Void>() {
@Override
public void onSuccess(Void done) {
}
@Override
public void onFailure(Throwable cause) {
LOG.error("addComplete processing failed for {} entry {} lastTxId {} rc {} with error", new Object[] { fullyQualifiedLogSegment, entryId, transmitPacket.getRecordSet().getMaxTxId(), rc, cause });
}
});
// Race condition if we notify before the addComplete is enqueued.
transmitPacket.notifyTransmitComplete(effectiveRC.get());
outstandingTransmits.getAndDecrement();
} else {
// Notify transmit complete must be called before deferred processing in the
// sync case since otherwise callbacks in deferred processing may deadlock.
transmitPacket.notifyTransmitComplete(effectiveRC.get());
outstandingTransmits.getAndDecrement();
addCompleteDeferredProcessing(transmitPacket, entryId, effectiveRC.get());
}
}
use of com.twitter.util.Function0 in project distributedlog by twitter.
the class TestSafeQueueingFuturePool method testRejectedBackupFailure.
@Test
public void testRejectedBackupFailure() throws Exception {
TestFuturePool<Void> pool = new TestFuturePool<Void>();
final AtomicBoolean result = new AtomicBoolean(false);
pool.executor.shutdownNow();
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
Future<Void> future1 = pool.wrapper.apply(new Function0<Void>() {
public Void apply() {
try {
latch1.await();
} catch (Exception ex) {
}
return null;
}
});
// Enqueue a set of futures behind.
final int blockedCount = 100;
final ArrayList<Future<Void>> blockedFutures = new ArrayList<Future<Void>>(blockedCount);
final int[] doneArray = new int[blockedCount];
final AtomicInteger doneCount = new AtomicInteger(0);
for (int i = 0; i < blockedCount; i++) {
final int index = i;
blockedFutures.add(pool.wrapper.apply(new Function0<Void>() {
public Void apply() {
doneArray[index] = doneCount.getAndIncrement();
return null;
}
}));
}
// All the futures fail when the executor is force closed.
latch1.countDown();
pool.executor.shutdownNow();
for (int i = 0; i < blockedCount; i++) {
try {
Await.result(blockedFutures.get(i));
fail("should have thrown");
} catch (RejectedExecutionException ex) {
}
}
// None of them have completed.
for (int i = 0; i < blockedCount; i++) {
assertEquals(0, doneArray[i]);
}
// Close cleans up all pending ops in order.
pool.wrapper.close();
for (int i = 0; i < blockedCount; i++) {
assertEquals(i, doneArray[i]);
}
pool.shutdown();
}
use of com.twitter.util.Function0 in project distributedlog by twitter.
the class SafeQueueingFuturePool method apply.
public synchronized Future<T> apply(final Function0<T> fn) {
Preconditions.checkNotNull(fn);
if (closed) {
return Future.exception(new RejectedExecutionException("Operation submitted to closed SafeQueueingFuturePool"));
}
++outstanding;
queue.add(fn);
Future<T> result = orderedFuturePool.apply(new Function0<T>() {
@Override
public T apply() {
return queue.poll().apply();
}
@Override
public String toString() {
return fn.toString();
}
}).ensure(new Function0<BoxedUnit>() {
public BoxedUnit apply() {
if (decrOutstandingAndCheckDone()) {
applyAll();
}
return null;
}
});
return result;
}
Aggregations