'Async Spring Controllers vs normal Controllers
I wanted to analyze the improvement I may see by enabling Async Controllers in Spring Boot over normal controller
So here is my test code. One API returns a Callable and another is normal controller API. Both APIs block for 10secs simulating a long running task
@RequestMapping(value="/api/1",method=RequestMethod.GET)
public List<String> questions() throws InterruptedException{
Thread.sleep(10000);
return Arrays.asList("Question1","Question2");
}
@RequestMapping(value="/api/2",method=RequestMethod.GET)
public Callable<List<String>> questionsAsync(){
return () -> {
Thread.sleep(10000);
return Arrays.asList("Question2","Question2");
};
}
I set up embedded tomcat with this configuration i.e only one tomcat processing thread:
server.tomcat.max-threads=1
logging.level.org.springframework=debug
Expectations for /api/1 Since there is only one tomcat thread, another request will not be entertained untill this is processed after 10secs
Results: Meet expectations
Expectations for /api/2 Since we are returning a callable immediately, the single tomcat thread should get free to process another request. Callable would internally start a new thread. So if you hit the same api it should also gets accepted.
Results: This is not happening and untill the callable executes completely, no further request is entertained.
Question Why is /api/2 not behaving as expected?
Solution 1:[1]
@DaveSyer is right, /api/2 is actually behaving as expected.
I assume you are testing the behavior with a web browser. At least Firefox and Chrome are preventing multiple simultaneous requests to the same URL. If you open 2 tabs with api/2, the second one will only send a request to the application after the first got the response.
Try testing it with a simple bash script, like:
curl localhost/api/2 &
curl localhost/api/2 &
curl localhost/api/2 &
It will print 3 responses around the same time.
Solution 2:[2]
Just want to mention that server.tomcat.max-threads is deprecated since Spring boot 2.3. Now use server.tomcat.threads.max in your Spring application.properties. The default is 200.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jakub Wach |
| Solution 2 | ouflak |
