Description
idleConnectionTimeout is "to expire connections idle more than that amount of time". I tried async-http-client version 1.7.2 and I was using NettyAsyncHttpProvider. What I found is that if idleConnectionTimeout is less than requestTimeout, then the idleConnectionTimeout is not effective. In my application, I set requestTimeout to be large so that it can handle transmission of a large file; I set idleConnectionTimeout to be small in hopes that it will quickly times out and do whatever it needs to do when the network connection is down or the other end isn't responding. But from what I can tell, the idleConnectionTimeout doesn't terminate idle connections if idleConnectionTimeout is less than requestTimeout. The connection hangs until requestTimeout kicks in. I think idleConnectionTimeout should be independent of requestTimeout. I did some digging into the code:
In ApacheAsyncHttpProvider.java/execute(), idleConnectionTimeoutThread is only set when idleConnectionTimeout is greater than requestTimeout:
...
int requestTimeout = requestTimeout(config, request.getPerRequestConfig());
if (config.getIdleConnectionTimeoutInMs() > 0 && requestTimeout != -1 && requestTimeout < config.getIdleConnectionTimeoutInMs()) {
idleConnectionTimeoutThread = new IdleConnectionTimeoutThread();
idleConnectionTimeoutThread.setConnectionTimeout(config.getIdleConnectionTimeoutInMs());
idleConnectionTimeoutThread.addConnectionManager(connectionManager);
idleConnectionTimeoutThread.start();
}
...
In NettyAsyncHttpProvider.java/writeRequest(), reaperFuture is scheduled at the rate of requestTimeout. So if idleConnectionTimeout is less, the idleness won't be checked:
...
try {
future.touch();
int delay = requestTimeout(config, future.getRequest().getPerRequestConfig());
if (delay != -1 && !future.isDone() && !future.isCancelled()) {
ReaperFuture reaperFuture = new ReaperFuture(future);
Future<?> scheduledFuture = config.reaper().scheduleAtFixedRate(reaperFuture, 0, delay, TimeUnit.MILLISECONDS);
reaperFuture.setScheduledFuture(scheduledFuture);
future.setReaperFuture(reaperFuture);
}
} catch (RejectedExecutionException ex) {
abort(future, ex);
}
...