Spring – How to set a timeout on Spring’s AsyncRestTemplate

asynchronousresttemplatespringspring-mvc

I've setup a RestTemplate and an AsyncRestTemplate in my project similar to the following:

http://vincentdevillers.blogspot.fr/2013/10/a-best-spring-asyncresttemplate.html

I've noticed that the connect timeout doesn't actually work unless I change the httpRequestFactory() bean to be the following:

@Bean
public ClientHttpRequestFactory httpRequestFactory() {
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient());
    factory.setConnectTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
    factory.setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
    return factory;
}

If I set DEFAULT_READ_TIMEOUT_MILLISECONDS to 5, a timeout occurs when I use restTemplate (as expected). However, when I use AsyncRestTemplate, a timeout doesn't occur. I've modified the asyncHttpRequestFactory() like httpRequestFactory(), but no dice.

@Bean
public AsyncClientHttpRequestFactory asyncHttpRequestFactory() {
    HttpComponentsAsyncClientHttpRequestFactory factory = new HttpComponentsAsyncClientHttpRequestFactory(asyncHttpClient());
    factory.setConnectTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
    factory.setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
    return factory;
}

Here's how I'm attempting to use AsyncRestTemplate in a Spring MVC Controller:

String url = "...";
// Start the clock
long start = System.currentTimeMillis();

ListenableFuture<ResponseEntity<String>> results = asyncRestTemplate.getForEntity(url, String.class);
// Wait until the request is finished
while (!(results.isDone())) {
    Thread.sleep(10); //millisecond pause between each check
}
System.out.println("Elapsed time: " + (System.currentTimeMillis() - start));
return results.get().getBody();

How can I get AsyncRestTemplate to read my connection timeout settings?

On a related note, https://spring.io/guides/gs/async-method/ uses @Async and RestTemplate and seems to accomplish what I'm looking for. What's the advantage of using AsyncRestTemplate over RestTemplate?

Best Answer

Very similar to the sync one:

final SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setTaskExecutor(new SimpleAsyncTaskExecutor());
requestFactory.setConnectTimeout(connectTimeout);
requestFactory.setReadTimeout(readTimeout);

final AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();
asyncRestTemplate.setAsyncRequestFactory(requestFactory); 

From the source code, you can see that AsyncRestTemplate instance is created by using a SimpleClientHttpRequestFactory together with a SimpleAsyncTaskExecutor. So you can just do the same using a SimpleClientHttpRequestFactory instance whose timeout values are set.