in httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpRequestRetryExec.java [99:196]
public ClassicHttpResponse execute(
final ClassicHttpRequest request,
final Scope scope,
final ExecChain chain) throws IOException, HttpException {
Args.notNull(request, "request");
Args.notNull(scope, "scope");
final String exchangeId = scope.exchangeId;
final HttpRoute route = scope.route;
final HttpClientContext context = scope.clientContext;
ClassicHttpRequest currentRequest = request;
for (int execCount = 1;; execCount++) {
final ClassicHttpResponse response;
try {
response = chain.proceed(currentRequest, scope);
} catch (final IOException ex) {
if (scope.execRuntime.isExecutionAborted()) {
throw new RequestFailedException("Request aborted");
}
final HttpEntity requestEntity = request.getEntity();
if (requestEntity != null && !requestEntity.isRepeatable()) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} cannot retry non-repeatable request", exchangeId);
}
throw ex;
}
if (retryStrategy.retryRequest(request, ex, execCount, context)) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} {}", exchangeId, ex.getMessage(), ex);
}
if (LOG.isInfoEnabled()) {
LOG.info("Recoverable I/O exception ({}) caught when processing request to {}",
ex.getClass().getName(), route);
}
final TimeValue nextInterval = retryStrategy.getRetryInterval(request, ex, execCount, context);
if (TimeValue.isPositive(nextInterval)) {
try {
if (LOG.isDebugEnabled()) {
LOG.debug("{} wait for {}", exchangeId, nextInterval);
}
nextInterval.sleep();
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
throw new InterruptedIOException();
}
}
currentRequest = ClassicRequestBuilder.copy(scope.originalRequest).build();
continue;
}
if (ex instanceof NoHttpResponseException) {
final NoHttpResponseException updatedex = new NoHttpResponseException(
route.getTargetHost().toHostString() + " failed to respond");
updatedex.setStackTrace(ex.getStackTrace());
throw updatedex;
}
throw ex;
}
try {
final HttpEntity entity = request.getEntity();
if (entity != null && !entity.isRepeatable()) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} cannot retry non-repeatable request", exchangeId);
}
return response;
}
if (retryStrategy.retryRequest(response, execCount, context)) {
final TimeValue nextInterval = retryStrategy.getRetryInterval(response, execCount, context);
// Make sure the retry interval does not exceed the response timeout
if (TimeValue.isPositive(nextInterval)) {
final RequestConfig requestConfig = context.getRequestConfigOrDefault();
final Timeout responseTimeout = requestConfig.getResponseTimeout();
if (responseTimeout != null && nextInterval.compareTo(responseTimeout) > 0) {
return response;
}
}
response.close();
if (TimeValue.isPositive(nextInterval)) {
try {
if (LOG.isDebugEnabled()) {
LOG.debug("{} wait for {}", exchangeId, nextInterval);
}
nextInterval.sleep();
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
throw new InterruptedIOException();
}
}
currentRequest = ClassicRequestBuilder.copy(scope.originalRequest).build();
} else {
return response;
}
} catch (final RuntimeException ex) {
response.close();
throw ex;
}
}
}