@Override public V get() throws ExecutionException, InterruptedException { return immediateFuture.get(); }
@Override public void addListener(Runnable runnable, Executor executor) { immediateFuture.addListener(runnable, executor); }
/** * This method is supposed to be called from {@link AttemptCallable#call()} * * @param ignored The ignored request; the actual request will be composed based on the result of * the {@code initialFuture}. * @param callContext call context */ @Override public ApiFuture<OperationSnapshot> futureCall(RequestT ignored, ApiCallContext callContext) { try { if (!initialFuture.isDone() || initialFuture.isCancelled()) { return initialFuture; } // Since initialFuture is done at this point, the following call should be non-blocking OperationSnapshot initialOperation = initialFuture.get(); if (initialOperation.isDone()) { return initialFuture; } return longRunningClient .getOperationCallable() .futureCall(initialOperation.getName(), callContext); } catch (ExecutionException e) { return ApiFutures.immediateFailedFuture(e.getCause()); } catch (InterruptedException e) { return ApiFutures.immediateFailedFuture(e); } } }
@Test public void cancellationBeforeGetOnRetryingCallable() throws Exception { thrown.expect(CancellationException.class); Mockito.when(callInt.futureCall((Integer) Mockito.any(), (ApiCallContext) Mockito.any())) .thenReturn(SettableApiFuture.<Integer>create()); UnaryCallSettings<Integer, Integer> callSettings = RetryingTest.createSettings(FAST_RETRY_SETTINGS); UnaryCallable<Integer, Integer> callable = FakeCallableFactory.createUnaryCallable(callInt, callSettings, clientContext); ApiFuture<Integer> resultFuture = callable.futureCall(0); resultFuture.cancel(true); resultFuture.get(); }
@Test public void testFutureCallInitialCancel() throws Exception { String opName = "testFutureCallInitialCancel"; OperationSnapshot initialOperation = getOperation(opName, null, null, null, false); OperationSnapshot resultOperation = getOperation(opName, null, null, null, false); UnaryCallable<Integer, OperationSnapshot> initialCallable = mockGetOpSnapshotCallable(StatusCode.Code.OK, initialOperation); LongRunningClient longRunningClient = mockGetOperation(StatusCode.Code.OK, resultOperation); OperationCallableImpl<Integer, Color, Currency> callableImpl = Callables.longRunningOperationImpl( initialCallable, callSettings, initialContext, longRunningClient); OperationFutureImpl<Color, Currency> future = callableImpl.futureCall( new ListenableFutureToApiFuture<>( Futures.<OperationSnapshot>immediateCancelledFuture()), FakeCallContext.createDefault()); Exception exception = null; try { future.get(3, TimeUnit.SECONDS); } catch (CancellationException e) { exception = e; } assertThat(exception).isNotNull(); assertThat(future.isDone()).isTrue(); assertThat(future.isCancelled()).isTrue(); assertThat(future.getInitialFuture().isDone()).isTrue(); assertThat(future.getInitialFuture().isCancelled()).isTrue(); assertFutureCancelMetaCancel(future); assertThat(executor.getIterationsCount()).isEqualTo(0); }
@Test public void translateException_cancelled() throws Exception { GrpcExceptionCallable<Integer, Integer> exceptionCallable = new GrpcExceptionCallable<>(inactiveCallable(), Collections.<StatusCode.Code>emptySet()); ApiFuture<Integer> result = exceptionCallable.futureCall(0); Truth.assertThat(result.isDone()).isFalse(); result.cancel(true); Truth.assertThat(result.isCancelled()).isTrue(); Truth.assertThat(result.isDone()).isTrue(); }
@Override public boolean cancel(final boolean mayInterruptIfRunning) { future.cancel(mayInterruptIfRunning); return super.cancel(mayInterruptIfRunning); }
/** * This method is supposed to be called from {@link AttemptCallable#call()} * * @param ignored The ignored request; the actual request will be composed based on the result of * the {@code initialFuture}. * @param callContext call context */ @Override public ApiFuture<OperationSnapshot> futureCall(RequestT ignored, ApiCallContext callContext) { try { if (!initialFuture.isDone() || initialFuture.isCancelled()) { return initialFuture; } // Since initialFuture is done at this point, the following call should be non-blocking OperationSnapshot initialOperation = initialFuture.get(); if (initialOperation.isDone()) { return initialFuture; } return longRunningClient .getOperationCallable() .futureCall(initialOperation.getName(), callContext); } catch (ExecutionException e) { return ApiFutures.immediateFailedFuture(e.getCause()); } catch (InterruptedException e) { return ApiFutures.immediateFailedFuture(e); } } }
@Test public void testEarlyTermination() throws Exception { ApiFuture<String> result = callable.futureCall("request"); MockServerStreamingCall<String, String> call = upstream.popLastCall(); // callable should request a single element on start Truth.assertThat(call.getController().isAutoFlowControlEnabled()).isFalse(); Truth.assertThat(call.getController().popLastPull()).isEqualTo(1); // Then the user promptly cancels it result.cancel(true); // The cancellation should propagate to the inner callable Truth.assertThat(call.getController().isCancelled()).isTrue(); // Then we fake a cancellation going the other way (it will be wrapped in StatusRuntimeException // for grpc) call.getController() .getObserver() .onError(new RuntimeException("Some other upstream cancellation notice")); Throwable actualError = null; try { result.get(1, TimeUnit.SECONDS); } catch (Throwable e) { actualError = e; } // However, that exception will be ignored and will be replaced by a generic CancellationException Truth.assertThat(actualError).isInstanceOf(CancellationException.class); }
assertFalse(future.getAttemptResult().isDone()); assertFalse(future.getAttemptResult().isCancelled());
public void flush() { // BUG(1795): We should force batcher to issue RPC call for buffered messages, // so the code below doesn't wait uselessly. ArrayList<ApiFuture<Void>> writesToFlush = new ArrayList<>(); synchronized (writeLock) { writesToFlush.addAll(pendingWrites); } try { ApiFutures.allAsList(writesToFlush).get(FLUSH_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { throw new RuntimeException(e); } }
private void assertFutureSuccessMetaSuccess( String opName, OperationFuture<Color, Money> future, Color resp, Money meta) throws Exception { assertThat(future.getName()).isEqualTo(opName); assertThat(future.get(3, TimeUnit.SECONDS)).isEqualTo(resp); assertThat(future.isDone()).isTrue(); assertThat(future.isCancelled()).isFalse(); assertThat(future.get()).isEqualTo(resp); assertThat(future.peekMetadata().get()).isEqualTo(meta); assertThat(future.peekMetadata()).isSameAs(future.peekMetadata()); assertThat(future.peekMetadata().isDone()).isTrue(); assertThat(future.peekMetadata().isCancelled()).isFalse(); assertThat(future.getMetadata().get()).isEqualTo(meta); assertThat(future.getMetadata()).isSameAs(future.getMetadata()); assertThat(future.getMetadata().isDone()).isTrue(); assertThat(future.getMetadata().isCancelled()).isFalse(); }
@Test public void testSinglePublishByNumBytes() throws Exception { Publisher publisher = getTestPublisherBuilder() .setBatchingSettings( Publisher.Builder.DEFAULT_BATCHING_SETTINGS .toBuilder() .setElementCountThreshold(2L) .setDelayThreshold(Duration.ofSeconds(100)) .build()) .build(); testPublisherServiceImpl .addPublishResponse(PublishResponse.newBuilder().addMessageIds("1").addMessageIds("2")) .addPublishResponse(PublishResponse.newBuilder().addMessageIds("3").addMessageIds("4")); ApiFuture<String> publishFuture1 = sendTestMessage(publisher, "A"); ApiFuture<String> publishFuture2 = sendTestMessage(publisher, "B"); ApiFuture<String> publishFuture3 = sendTestMessage(publisher, "C"); // Note we are not advancing time but message should still get published assertEquals("1", publishFuture1.get()); assertEquals("2", publishFuture2.get()); assertFalse(publishFuture3.isDone()); ApiFuture<String> publishFuture4 = sendTestMessage(publisher, "D"); assertEquals("3", publishFuture3.get()); assertEquals("4", publishFuture4.get()); assertEquals(2, testPublisherServiceImpl.getCapturedRequests().size()); publisher.shutdown(); publisher.awaitTermination(1, TimeUnit.MINUTES); }
@Test public void testEarlyTermination() throws Exception { ApiFuture<List<String>> result = callable.futureCall("request"); MockServerStreamingCall<String, String> call = upstream.popLastCall(); // The caller cancels the stream while receiving responses call.getController().getObserver().onResponse("response1"); result.cancel(true); call.getController().getObserver().onResponse("response2"); // The cancellation should propagate upstream Truth.assertThat(call.getController().isCancelled()).isTrue(); // Then we fake a cancellation going the other way (it will be wrapped in StatusRuntimeException // for grpc) call.getController() .getObserver() .onError(new RuntimeException("Some other upstream cancellation indicator")); // However the inner cancellation exception will be masked by an outer CancellationException expectedException.expect(CancellationException.class); result.get(); }
@Test public void testSuccessWithFailuresPeekGetAttempt() throws Exception { FailingCallable callable = new FailingCallable(5, "SUCCESS", tracer); RetryingExecutorWithContext<String> executor = getExecutor(getAlgorithm(FAST_RETRY_SETTINGS, 0, null)); RetryingFuture<String> future = executor.createFuture(callable, retryingContext); assertNull(future.peekAttemptResult()); assertSame(future.peekAttemptResult(), future.peekAttemptResult()); assertFalse(future.getAttemptResult().isDone()); assertFalse(future.getAttemptResult().isCancelled()); Exception exception = null; try { future.get(1L, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { exception = e; } assertNotNull(exception); future.setAttemptFuture(executor.submit(future)); assertFutureSuccess(future); assertEquals(5, future.getAttemptSettings().getAttemptCount()); }
@Override public void addListener(Runnable runnable, Executor executor) { initialFuture.addListener(runnable, executor); }
@Test public void serializeBasicTypes() throws Exception { doReturn(SINGLE_WRITE_COMMIT_RESPONSE) .when(firestoreMock) .sendRequest( commitCapture.capture(), Matchers.<UnaryCallable<CommitRequest, CommitResponse>>any()); documentReference.set(ALL_SUPPORTED_TYPES_MAP).get(); documentReference.set(ALL_SUPPORTED_TYPES_OBJECT).get(); CommitRequest expectedCommit = commit(set(ALL_SUPPORTED_TYPES_PROTO)); assertCommitEquals(expectedCommit, commitCapture.getAllValues().get(0)); assertCommitEquals(expectedCommit, commitCapture.getAllValues().get(1)); }
private void assertFutureSuccessMetaSuccess( String opName, OperationFuture<Color, Currency> future, Color resp, Currency meta) throws InterruptedException, ExecutionException, TimeoutException { assertThat(future.getName()).isEqualTo(opName); Truth.assertThat(future.get(3, TimeUnit.SECONDS)).isEqualTo(resp); assertThat(future.isDone()).isTrue(); assertThat(future.isCancelled()).isFalse(); Truth.assertThat(future.get()).isEqualTo(resp); Truth.assertThat(future.peekMetadata().get()).isEqualTo(meta); assertThat(future.peekMetadata()).isSameAs(future.peekMetadata()); assertThat(future.peekMetadata().isDone()).isTrue(); assertThat(future.peekMetadata().isCancelled()).isFalse(); Truth.assertThat(future.getMetadata().get()).isEqualTo(meta); assertThat(future.getMetadata()).isSameAs(future.getMetadata()); assertThat(future.getMetadata().isDone()).isTrue(); assertThat(future.getMetadata().isCancelled()).isFalse(); }