dzieciou
dzieciou

Reputation: 4524

Why there are no delays between retries in Apache HTTP Client?

When Apache HTTP Client fails to connect to a server (IOException) it may try to retryconnecting. However, it does not wait until retrying next time. This seems counterintuive, for instance when the target server is recovering or getting up, it may need some time to become ready for new requests.

Why is it so?

Here's a corresponding code from DefaultRequestDirector:

for (;;) {
    context.setAttribute(ExecutionContext.HTTP_REQUEST, wrapper);
    // Increment connect count
    connectCount++;
    try {
        if (!managedConn.isOpen()) {
            managedConn.open(route, context, params);
        } else {
            managedConn.setSocketTimeout(HttpConnectionParams.getSoTimeout(params));
        }
        establishRoute(route, context);
        break;
    } catch (final IOException ex) {
        try {
            managedConn.close();
        } catch (final IOException ignore) {
        }
        if (retryHandler.retryRequest(ex, connectCount, context)) {
            ...
        } else {
            throw ex;
        }
    }
}

Upvotes: 1

Views: 1064

Answers (1)

Ioannis Sermetziadis
Ioannis Sermetziadis

Reputation: 797

DefaultRequestDirector indeed has this hard-coded logic of intentionally ignoring IOException. However, this API was deprecated in 4.3 and at 4.3+ you can directly set a RetryHandler to the HttpClientBuilder.

You will need to override the DefaultHttpRequestRetryHandler that also ignores ConnectionException, but in a more configurable way, by defining a list of non-retriable-classes (unfortunately, this constructor is protected, so a subclass needs to be created to expose that constructor).

    CustomHttpRequestRetryHandler myRetryHandler = new CustomHttpRequestRetryHandler(3, false, 
        Collections.<Class<? extends IOException>>emptyList());
    CloseableHttpClient client = HttpClients.custom()
        .setRetryHandler(myRetryHandler)
        .build();

    private static class CustomHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {
        public CustomHttpRequestRetryHandler(int retryCount, boolean requestSentRetryEnabled, Collection<Class<? extends IOException>> clazzes) {
            super(retryCount, requestSentRetryEnabled, clazzes);
        }
    }

good luck!

Upvotes: 1

Related Questions