while (messageIdFuture.isDone()) { Thread.sleep(500L);
@Test public void testPublishByDuration() throws Exception { Publisher publisher = getTestPublisherBuilder() // To demonstrate that reaching duration will trigger publish .setBatchingSettings( Publisher.Builder.DEFAULT_BATCHING_SETTINGS .toBuilder() .setDelayThreshold(Duration.ofSeconds(5)) .setElementCountThreshold(10L) .build()) .build(); testPublisherServiceImpl.addPublishResponse( PublishResponse.newBuilder().addMessageIds("1").addMessageIds("2")); ApiFuture<String> publishFuture1 = sendTestMessage(publisher, "A"); ApiFuture<String> publishFuture2 = sendTestMessage(publisher, "B"); assertFalse(publishFuture1.isDone()); assertFalse(publishFuture2.isDone()); fakeExecutor.advanceTime(Duration.ofSeconds(10)); assertEquals("1", publishFuture1.get()); assertEquals("2", publishFuture2.get()); assertEquals(2, testPublisherServiceImpl.getCapturedRequests().get(0).getMessagesCount()); publisher.shutdown(); publisher.awaitTermination(1, TimeUnit.MINUTES); }
@Test public void testPublishByNumBatchedMessages() 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 = publisher.publish(PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8("D")).build()); assertEquals("3", publishFuture3.get()); assertEquals("4", publishFuture4.get()); assertEquals(2, testPublisherServiceImpl.getCapturedRequests().get(0).getMessagesCount()); assertEquals(2, testPublisherServiceImpl.getCapturedRequests().get(1).getMessagesCount()); publisher.shutdown(); publisher.awaitTermination(1, TimeUnit.MINUTES); }
@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); }
@Override public void run() { try { latch.await(); while (!resultFuture.cancel(true) && !resultFuture.isDone()) { Thread.sleep(1L); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } });
@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(); }
/** * 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); } } }
/** * 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); } } }
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(); }
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(); }
ApiException cause = (ApiException) exception.getCause(); assertThat(cause.getStatusCode()).isEqualTo(statusCode); assertThat(future.peekMetadata().isDone()).isTrue(); assertThat(future.peekMetadata().isCancelled()).isFalse(); cause = (ApiException) exception.getCause(); assertThat(cause.getStatusCode()).isEqualTo(statusCode); assertThat(future.getMetadata().isDone()).isTrue(); assertThat(future.getMetadata().isCancelled()).isFalse();
private void assertFutureCancelMetaCancel(OperationFuture<Color, Currency> future) throws InterruptedException, ExecutionException, TimeoutException { 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(); try { future.peekMetadata().get(); } catch (CancellationException e) { exception = e; } assertThat(future.peekMetadata()).isSameAs(future.peekMetadata()); assertThat(exception).isNotNull(); assertThat(future.peekMetadata().isDone()).isTrue(); assertThat(future.peekMetadata().isCancelled()).isTrue(); try { future.getMetadata().get(); } catch (CancellationException e) { exception = e; } assertThat(future.getMetadata()).isSameAs(future.getMetadata()); assertThat(exception).isNotNull(); assertThat(future.getMetadata().isDone()).isTrue(); assertThat(future.getMetadata().isCancelled()).isTrue(); }
private void assertFutureFailMetaSuccess( OperationFuture<Color, Currency> future, Currency meta, FakeStatusCode statusCode, String errorMessage) throws TimeoutException, InterruptedException, ExecutionException { Exception exception = null; try { future.get(3, TimeUnit.SECONDS); } catch (ExecutionException e) { exception = e; } assertThat(exception).isNotNull(); assertExceptionMatchesCode(statusCode, exception.getCause()); ApiException cause = (ApiException) exception.getCause(); assertThat(cause.getStatusCode()).isEqualTo(statusCode); assertThat(cause.getMessage()).isEqualTo(errorMessage); assertThat(future.isDone()).isTrue(); assertThat(future.isCancelled()).isFalse(); 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(); }
@Test public void cancellationDuringRetryDelay() throws Exception { Throwable throwable = new UnavailableException(null, FakeStatusCode.of(StatusCode.Code.UNAVAILABLE), true); CancellationTrackingFuture<Integer> innerFuture = CancellationTrackingFuture.create(); Mockito.when(callInt.futureCall((Integer) Mockito.any(), (ApiCallContext) Mockito.any())) .thenReturn(RetryingTest.<Integer>immediateFailedFuture(throwable)) .thenReturn(innerFuture); CountDownLatch retryScheduledLatch = new CountDownLatch(1); LatchCountDownScheduler scheduler = LatchCountDownScheduler.get(retryScheduledLatch, 0L, 0L); UnaryCallSettings<Integer, Integer> callSettings = RetryingTest.createSettings(SLOW_RETRY_SETTINGS); UnaryCallable<Integer, Integer> callable = FakeCallableFactory.createUnaryCallable( callInt, callSettings, clientContext.toBuilder().setExecutor(scheduler).build()); ApiFuture<Integer> resultFuture = callable.futureCall(0); CancellationHelpers.cancelInThreadAfterLatchCountDown(resultFuture, retryScheduledLatch); CancellationException gotException = null; try { resultFuture.get(); } catch (CancellationException e) { gotException = e; } Truth.assertThat(gotException).isNotNull(); Truth.assertThat(resultFuture.isDone()).isTrue(); Truth.assertThat(resultFuture.isCancelled()).isTrue(); Truth.assertThat(innerFuture.isCancelled()).isFalse(); scheduler.shutdownNow(); }
Truth.assertThat(resultFuture.isDone()).isTrue(); Truth.assertThat(resultFuture.isCancelled()).isTrue(); Truth.assertThat(innerFuture.isDone()).isTrue();
@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 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()); }
void assertFutureSuccess(RetryingFuture<String> future) throws ExecutionException, InterruptedException, TimeoutException { assertEquals("SUCCESS", future.get(3, TimeUnit.SECONDS)); assertTrue(future.isDone()); assertFalse(future.isCancelled()); assertEquals("SUCCESS", future.peekAttemptResult().get(3, TimeUnit.SECONDS)); assertSame(future.peekAttemptResult(), future.peekAttemptResult()); assertTrue(future.peekAttemptResult().isDone()); assertFalse(future.peekAttemptResult().isCancelled()); assertEquals("SUCCESS", future.getAttemptResult().get(3, TimeUnit.SECONDS)); assertSame(future.getAttemptResult(), future.getAttemptResult()); assertTrue(future.getAttemptResult().isDone()); assertFalse(future.getAttemptResult().isCancelled()); String res = future.get(); ApiFuture<?> gottentAttempt = future.getAttemptResult(); ApiFuture<?> peekedAttempt = future.peekAttemptResult(); // testing completed immutability assertFalse(future.cancel(true)); assertFalse(future.cancel(false)); assertSame(gottentAttempt, future.getAttemptResult()); assertSame(peekedAttempt, future.peekAttemptResult()); assertSame(res, future.get()); assertTrue(future.isDone()); assertFalse(future.isCancelled()); }