Since starting, I was always confuse of how to deal with InterruptedException and how to properly cancel the http request if they are taking too much time. I have a library
First of all, Why are you using SettableFuture? Why can't just return the ListenableFuture returned by AsyncRestTemplate?
1. Can we interrupt AsyncRestTemplate call if http request is taking too long?
Of course you do! You only need to call Future.cancel
method. This method will interrupt the execution of the internal RestTemplate that AsyncRestTemplate is actually using.
2. Also am I doing the right thing in catch block of InterruptedException in executeSync method?
As Phil and Danilo have said, you don't need to interrupt the current thread within the InterruptedException catch block. Just do whatever you need to do when the execution of the request must be canceled.
In fact, I recommend you create a method that handles this behaviour, something like handleInterruption, and use this method for both TimeoutException
and InterruptedException
.
3. Is it true that by default AsyncRestTamplete uses blocking calls and request per thread?
Yes. The default constructor of AsyncRestTamplete
is internally using SimpleClientHttpRequestFactory
and SimpleAsyncTaskExecutor
.
This TaskExecutor always starts a threat for every task, and never reuse Threads, so it's very inefficient:
* TaskExecutor implementation that fires up a new Thread for each task,
* executing it asynchronously.
*
* Supports limiting concurrent threads through the "concurrencyLimit"
* bean property. By default, the number of concurrent threads is unlimited.
*
* NOTE: This implementation does not reuse threads! Consider a
* thread-pooling TaskExecutor implementation instead, in particular for
* executing a large number of short-lived tasks.
*
I recommend you use another configuration of AsyncRestTemplate.
You should use the constructor of AsyncRestTemplate that uses another TaskExecutor:
public AsyncRestTemplate(AsyncListenableTaskExecutor taskExecutor)
For instance:
AsyncRestTemplate template = new AsyncRestTemplate(new ConcurrentTaskExecutor(Executors.newCachedThreadPool()));
This ExecutorService (Executors.newCachedThreadPool()) creates new threads as needed, but will reuse previously constructed threads when they are available.
Or even better, you can use another RequestFactory. For instance, you can use HttpComponentsAsyncClientHttpRequestFactory
, that internally uses NIO, just calling the proper constructor of AsyncRestTemplate:
new AsyncRestTemplate(new HttpComponentsAsyncClientHttpRequestFactory())
Don't forget the internal behaviour of AsyncRestTemplate will depend on how you create the object.