HttpAsyncClient HC5 request timeout

823 Views Asked by At

We are checking to use HttpAsyncClient from HttpClient 5.0 which will be created in Flink AsyncFunction. The requirements are the following:

  1. The client is created per request;
  2. SSL certificate should be loaded in run time from files;
  3. The request should be retried in case of failure specific count of times with delay
    This is part of the test:
final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create().setSslContext(sslContext).build();
final PoolingAsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create()
        .setTlsStrategy(tlsStrategy)
        .build();
try (final CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
        .setConnectionManager(cm)
        .setRetryStrategy(new RetryStrategy(3, TimeValue.ofMilliseconds(100)))
        .build()) {

    httpclient.start();
    RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(Timeout.of(1000, TimeUnit.MILLISECONDS))
        .setResponseTimeout(Timeout.of(1000, TimeUnit.MILLISECONDS))
        .build();
    HttpClientContext httpContext = HttpClientContext.create();
    httpContext.setRequestConfig(requestConfig);
    final Future<SimpleHttpResponse> futurePostRequest =
          httpclient.execute(request1, httpContext, null);
    class RetryStrategy extends DefaultHttpRequestRetryStrategy {
        public RetryStrategy(
                final int maxRetries,
                final TimeValue defaultRetryInterval) {
            super(maxRetries, defaultRetryInterval,
                    Arrays.asList(
//                            InterruptedIOException.class,
                            UnknownHostException.class,
//                            ConnectException.class,
                            ConnectionClosedException.class,
                            SSLException.class),
                    Arrays.asList(
                            HttpStatus.SC_TOO_MANY_REQUESTS,
                            HttpStatus.SC_SERVICE_UNAVAILABLE));
        }

        protected boolean handleAsIdempotent(final HttpRequest request) {
            return true;
        }
    }

DefaultHttpRequestRetryStrategy is overridden to allow retry in case of SocketTimeout exception.

On test of retry strategy against MOCK HTTP server with delay of 1200 milliseconds in responses I've figured out that part of requests are succeeded when I expected failure of all requests (since timeout is set to 1000 milliseconds). E.g. I’ve call the above code 10 times simultaneously and 3 of requests are succeeded. Does it means that response timeout can be more than configured? When I sent setMaxtTotal to connection manager (cm.setMaxTotal(100)) all of requests were failed as expected. Why does increase of connection fix the problem (Connection manager is created for each requests, it is not reused for new requests/clients)? Is it the correct solution to fix timeout issue?

Is usage of PoolingAsyncClientConnectionManager justified for our requirements? And if not how to configure SSL context and retry strategy in other way?

Thanks!

0

There are 0 best solutions below