@Test public void testNoRpcTimeout() { parentFuture.timedAttemptSettings = parentFuture.timedAttemptSettings.toBuilder().setRpcTimeout(Duration.ZERO).build(); MutateRowsRequest request = MutateRowsRequest.newBuilder().addEntries(Entry.getDefaultInstance()).build(); innerCallable.response.add( MutateRowsResponse.newBuilder() .addEntries( MutateRowsResponse.Entry.newBuilder().setIndex(0).setStatus(OK_STATUS_PROTO)) .build()); MutateRowsAttemptCallable attemptCallable = new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes); attemptCallable.setExternalFuture(parentFuture); attemptCallable.call(); assertThat(innerCallable.lastContext.getTimeout()).isNull(); }
@Before public void setUp() { capturedCallContext = ArgumentCaptor.forClass(ApiCallContext.class); Mockito.when(mockInnerCallable.futureCall(Mockito.<String>any(), capturedCallContext.capture())) .thenReturn(SettableApiFuture.<String>create()); currentAttemptSettings = TimedAttemptSettings.newBuilder() .setGlobalSettings(RetrySettings.newBuilder().build()) .setAttemptCount(0) .setOverallAttemptCount(0) .setFirstAttemptStartTimeNanos(0) .setRetryDelay(Duration.ofSeconds(1)) .setRandomizedRetryDelay(Duration.ofSeconds(1)) .setRpcTimeout(Duration.ZERO) .build(); Mockito.when(mockExternalFuture.getAttemptSettings()) .thenAnswer( new Answer<TimedAttemptSettings>() { @Override public TimedAttemptSettings answer(InvocationOnMock invocation) throws Throwable { return currentAttemptSettings; } }); }
@Before public void setUp() { capturedCallContext = ArgumentCaptor.forClass(ApiCallContext.class); Mockito.when(mockInnerCallable.futureCall(Mockito.anyString(), capturedCallContext.capture())) .thenReturn(SettableApiFuture.<String>create()); currentAttemptSettings = TimedAttemptSettings.newBuilder() .setGlobalSettings(RetrySettings.newBuilder().build()) .setAttemptCount(0) .setOverallAttemptCount(0) .setFirstAttemptStartTimeNanos(0) .setRetryDelay(Duration.ofSeconds(1)) .setRandomizedRetryDelay(Duration.ofSeconds(1)) .setRpcTimeout(Duration.ZERO) .build(); Mockito.when(mockExternalFuture.getAttemptSettings()) .thenAnswer( new Answer<TimedAttemptSettings>() { @Override public TimedAttemptSettings answer(InvocationOnMock invocation) throws Throwable { return currentAttemptSettings; } }); }
.setOverallAttemptCount(prevSettings.getOverallAttemptCount() + 1) .setFirstAttemptStartTimeNanos(prevSettings.getFirstAttemptStartTimeNanos()) .build();
.setOverallAttemptCount(prevSettings.getOverallAttemptCount() + 1) .setFirstAttemptStartTimeNanos(prevSettings.getFirstAttemptStartTimeNanos()) .build();
/** * {@inheritDoc} * * <p>The attempt settings will be reset if the stream attempt produced any messages. */ @Override public TimedAttemptSettings createNextAttempt( Throwable prevThrowable, ResponseT prevResponse, TimedAttemptSettings prevSettings) { if (prevThrowable instanceof ServerStreamingAttemptException) { ServerStreamingAttemptException attemptException = (ServerStreamingAttemptException) prevThrowable; prevThrowable = prevThrowable.getCause(); // If we have made progress in the last attempt, then reset the delays if (attemptException.hasSeenResponses()) { prevSettings = createFirstAttempt() .toBuilder() .setFirstAttemptStartTimeNanos(prevSettings.getFirstAttemptStartTimeNanos()) .setOverallAttemptCount(prevSettings.getOverallAttemptCount()) .build(); } } return super.createNextAttempt(prevThrowable, prevResponse, prevSettings); }
/** * {@inheritDoc} * * <p>The attempt settings will be reset if the stream attempt produced any messages. */ @Override public TimedAttemptSettings createNextAttempt( Throwable prevThrowable, ResponseT prevResponse, TimedAttemptSettings prevSettings) { if (prevThrowable instanceof ServerStreamingAttemptException) { ServerStreamingAttemptException attemptException = (ServerStreamingAttemptException) prevThrowable; prevThrowable = prevThrowable.getCause(); // If we have made progress in the last attempt, then reset the delays if (attemptException.hasSeenResponses()) { prevSettings = createFirstAttempt() .toBuilder() .setFirstAttemptStartTimeNanos(prevSettings.getFirstAttemptStartTimeNanos()) .setOverallAttemptCount(prevSettings.getOverallAttemptCount()) .build(); } } return super.createNextAttempt(prevThrowable, prevResponse, prevSettings); }
/** * Creates a first attempt {@link TimedAttemptSettings}. The first attempt is configured to be * executed immediately. * * @return first attempt settings */ @Override public TimedAttemptSettings createFirstAttempt() { return TimedAttemptSettings.newBuilder() .setGlobalSettings(globalSettings) .setRetryDelay(Duration.ZERO) .setRpcTimeout(globalSettings.getInitialRpcTimeout()) .setRandomizedRetryDelay(Duration.ZERO) .setAttemptCount(0) .setOverallAttemptCount(0) .setFirstAttemptStartTimeNanos(clock.nanoTime()) .build(); }
@Test public void testRpcTimeout() { CheckingAttemptCallable<String, String> callable = new CheckingAttemptCallable<>(mockInnerCallable, FakeCallContext.createDefault()); callable.setExternalFuture(mockExternalFuture); // Make sure that the rpc timeout is set Duration timeout = Duration.ofSeconds(10); currentAttemptSettings = currentAttemptSettings.toBuilder().setRpcTimeout(timeout).build(); callable.call(); assertThat(capturedCallContext.getValue().getTimeout()).isEqualTo(timeout); // Make sure that subsequent attempts can extend the time out Duration longerTimeout = Duration.ofSeconds(20); currentAttemptSettings = currentAttemptSettings.toBuilder().setRpcTimeout(longerTimeout).build(); callable.call(); assertThat(capturedCallContext.getValue().getTimeout()).isEqualTo(longerTimeout); } }
/** * Creates a first attempt {@link TimedAttemptSettings}. The first attempt is configured to be * executed immediately. * * @return first attempt settings */ @Override public TimedAttemptSettings createFirstAttempt() { return TimedAttemptSettings.newBuilder() .setGlobalSettings(globalSettings) .setRetryDelay(Duration.ZERO) .setRpcTimeout(globalSettings.getInitialRpcTimeout()) .setRandomizedRetryDelay(Duration.ZERO) .setAttemptCount(0) .setOverallAttemptCount(0) .setFirstAttemptStartTimeNanos(clock.nanoTime()) .build(); }
@Test public void testRpcTimeout() { AttemptCallable<String, String> callable = new AttemptCallable<>(mockInnerCallable, "fake-request", FakeCallContext.createDefault()); callable.setExternalFuture(mockExternalFuture); // Make sure that the rpc timeout is set Duration timeout = Duration.ofSeconds(10); currentAttemptSettings = currentAttemptSettings.toBuilder().setRpcTimeout(timeout).build(); callable.call(); assertThat(capturedCallContext.getValue().getTimeout()).isEqualTo(timeout); // Make sure that subsequent attempts can extend the time out Duration longerTimeout = Duration.ofSeconds(20); currentAttemptSettings = currentAttemptSettings.toBuilder().setRpcTimeout(longerTimeout).build(); callable.call(); assertThat(capturedCallContext.getValue().getTimeout()).isEqualTo(longerTimeout); }
@Override public TimedAttemptSettings createNextAttempt( Throwable prevThrowable, ResponseT prevResponse, TimedAttemptSettings prevSettings) { if (prevThrowable != null && prevThrowable instanceof DeadlineExceededException) { return TimedAttemptSettings.newBuilder() .setGlobalSettings(prevSettings.getGlobalSettings()) .setRetryDelay(prevSettings.getRetryDelay()) .setRpcTimeout(prevSettings.getRpcTimeout()) .setRandomizedRetryDelay(DEADLINE_SLEEP_DURATION) .setAttemptCount(prevSettings.getAttemptCount() + 1) .setFirstAttemptStartTimeNanos(prevSettings.getFirstAttemptStartTimeNanos()) .build(); } return null; }
FakeRetryingFuture(ServerStreamingAttemptCallable<String, String> attemptCallable) { this.attemptCallable = attemptCallable; attemptSettings = TimedAttemptSettings.newBuilder() .setGlobalSettings( RetrySettings.newBuilder().setTotalTimeout(Duration.ofHours(1)).build()) .setFirstAttemptStartTimeNanos(0) .setAttemptCount(0) .setOverallAttemptCount(0) .setRandomizedRetryDelay(Duration.ofMillis(1)) .setRetryDelay(Duration.ofMillis(1)) .setRpcTimeout(Duration.ofMinutes(1)) .build(); }
@Override public TimedAttemptSettings createNextAttempt( Throwable prevThrowable, ResponseT prevResponse, TimedAttemptSettings prevSettings) { if (prevThrowable != null && prevThrowable instanceof DeadlineExceededException) { return TimedAttemptSettings.newBuilder() .setGlobalSettings(prevSettings.getGlobalSettings()) .setRetryDelay(prevSettings.getRetryDelay()) .setRpcTimeout(prevSettings.getRpcTimeout()) .setRandomizedRetryDelay(DEADLINE_SLEEP_DURATION) .setAttemptCount(prevSettings.getAttemptCount() + 1) .setFirstAttemptStartTimeNanos(prevSettings.getFirstAttemptStartTimeNanos()) .build(); } return null; }
MockRetryingFuture(Duration totalTimeout) { this.timedAttemptSettings = TimedAttemptSettings.newBuilder() .setRpcTimeout(Duration.ofSeconds(1)) .setRetryDelay(Duration.ZERO) .setRandomizedRetryDelay(Duration.ZERO) .setAttemptCount(0) .setFirstAttemptStartTimeNanos(0) .setGlobalSettings(RetrySettings.newBuilder().setTotalTimeout(totalTimeout).build()) .build(); }