@Test public void test408ShouldRetry() { HttpCommand command = createMock(HttpCommand.class); HttpResponse response = createMock(HttpResponse.class); @SuppressWarnings("unchecked") LoadingCache<Credentials, Access> cache = createMock(LoadingCache.class); BackoffLimitedRetryHandler backoffHandler = createMock(BackoffLimitedRetryHandler.class); expect(response.getPayload()) .andReturn( Payloads.newStringPayload( "The server has waited too long for the request to be sent by the client.")) .times(3); expect(backoffHandler.shouldRetryRequest(command, response)).andReturn(true).once(); expect(response.getStatusCode()).andReturn(408).once(); replay(command); replay(response); replay(cache); replay(backoffHandler); RetryOnRenew retry = new RetryOnRenew(cache, backoffHandler); assertTrue(retry.shouldRetryRequest(command, response)); verify(command); verify(response); verify(cache); verify(backoffHandler); }
public static <F, T> Iterable<T> transformParallel( Iterable<F> fromIterable, Function<? super F, Future<T>> function, ExecutorService exec, @Nullable Long maxTime, Logger logger, String logPrefix, BackoffLimitedRetryHandler retryHandler, int maxRetries) { Map<F, Exception> exceptions = newHashMap(); Map<F, Future<T>> responses = newHashMap(); for (int i = 0; i < maxRetries; i++) { for (F from : fromIterable) { responses.put(from, function.apply(from)); } exceptions = awaitCompletion(responses, exec, maxTime, logger, logPrefix); if (exceptions.size() > 0) { fromIterable = exceptions.keySet(); retryHandler.imposeBackoffExponentialDelay( delayStart, 2, i + 1, maxRetries, String.format("error %s: %s: %s", logPrefix, fromIterable, exceptions)); } else { break; } } if (exceptions.size() > 0) throw new RuntimeException( String.format("error %s: %s: %s", logPrefix, fromIterable, exceptions)); return unwrap(responses.values()); }
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) { if (command.getFailureCount() > retryCountLimit) return false; if (response.getStatusCode() == 404 && command.getCurrentRequest().getMethod().equals("DELETE")) { command.incrementFailureCount(); return true; } else if (response.getStatusCode() == 409) { byte[] content = HttpUtils.closeClientButKeepContentStream(response); // Content can be null in the case of HEAD requests if (content != null) { try { AtmosError error = utils.parseAtmosErrorFromContent(command, response, new String(content)); if (error.getCode() == 1006) { return backoffHandler.shouldRetryRequest(command, response); } // don't increment count before here, since backoff handler does already command.incrementFailureCount(); } catch (HttpException e) { logger.warn(e, "error parsing response: %s", new String(content)); } } else { command.incrementFailureCount(); } return true; } return false; }
private void backoffForAttempt(int retryAttempt, String message) { backoffLimitedRetryHandler.imposeBackoffExponentialDelay( 200L, 2, retryAttempt, sshRetries, message); }