public BufferedOperation(Deferred<LocatedTablet> tablet, Operation operation) { tabletLookup = AsyncUtil.addBoth(tablet, new Callback<Void, Object>() { @Override public Void call(final Object tablet) { BufferedOperation.this.tablet = tablet; return null; } }); this.operation = Preconditions.checkNotNull(operation); }
/** * Returns a flush notification for the currently non-active buffers. * This is used during manual {@link #flush} calls to ensure that all buffers (not just the active * buffer) are fully flushed before completing. */ @GuardedBy("monitor") private Deferred<Void> getNonActiveFlushNotification() { final Deferred<Void> notificationA = bufferA.getFlushNotification(); final Deferred<Void> notificationB = bufferB.getFlushNotification(); if (activeBuffer == null) { // Both buffers are either flushing or inactive. return AsyncUtil.addBothDeferring(notificationA, new Callback<Deferred<Void>, Object>() { @Override public Deferred<Void> call(Object obj) throws Exception { return notificationB; } }); } else if (activeBuffer == bufferA) { return notificationB; } else { return notificationA; } }
@Test public void testAddCallbacksDeferring() throws Exception { Deferred<String> d = new Deferred<String>(); TestCallback cb = new TestCallback(); TestErrback eb = new TestErrback(); // Test normal callbacks. AsyncUtil.addCallbacksDeferring(d, cb, eb); final String testStr = "hello world"; d.callback(testStr); assertEquals(d.join(), "callback: " + testStr); d = new Deferred<String>(); AsyncUtil.addCallbacksDeferring(d, cb, eb); d.callback(new IllegalArgumentException()); assertEquals(d.join(), "illegal arg"); d = new Deferred<String>(); AsyncUtil.addCallbacksDeferring(d, cb, eb); d.callback(new IllegalStateException()); exception.expect(IllegalStateException.class); d.join(); }
Deferred<Master.GetTableLocationsResponsePB> returnedD = locateTablet(request.getTable(), partitionKey, FETCH_TABLETS_PER_POINT_LOOKUP, request); return AsyncUtil.addCallbacksDeferring(returnedD, cb, eb);
/** * Flushes a write buffer. This method takes ownership of the buffer, no other concurrent access * is allowed. * * @param buffer the buffer to flush, must not be modified once passed to this method * @return the operation responses */ private Deferred<List<OperationResponse>> doFlush(Buffer buffer) { LOG.debug("flushing buffer: {}", buffer); if (buffer.getOperations().isEmpty()) { // no-op. return Deferred.<List<OperationResponse>>fromResult(ImmutableList.<OperationResponse>of()); } Deferred<List<BatchResponse>> batchResponses = new Deferred<>(); Callback<Void, Object> tabletLookupCB = new TabletLookupCB(buffer, batchResponses); for (BufferedOperation bufferedOperation : buffer.getOperations()) { AsyncUtil.addBoth(bufferedOperation.getTabletLookup(), tabletLookupCB); } return batchResponses.addCallback(ConvertBatchToListOfResponsesCB.getInstance()); }
/** * Flush buffered writes. * @return a {@link Deferred} whose callback chain will be invoked when all applied operations at * the time of the call have been flushed. */ public Deferred<List<OperationResponse>> flush() { Buffer buffer; Deferred<Void> nonActiveBufferFlush; synchronized (monitor) { nonActiveBufferFlush = getNonActiveFlushNotification(); buffer = activeBuffer; activeBuffer = null; } final Deferred<List<OperationResponse>> activeBufferFlush = buffer == null ? Deferred.<List<OperationResponse>>fromResult(ImmutableList.<OperationResponse>of()) : doFlush(buffer); return AsyncUtil.addBothDeferring(nonActiveBufferFlush, new Callback<Deferred<List<OperationResponse>>, Object>() { @Override public Deferred<List<OperationResponse>> call(Object arg) { return activeBufferFlush; } }); }
AsyncUtil.addBoth( Deferred.group(batchResponses), new Callback<Void, Object>() {