There are multiple ways to do this. Using DeferredResult
is probably the easiest way:
@RestController
public class Controller {
private final Executor performancePool = Executors.newFixedThreadPool(128);
private final Executor normalPool = Executors.newFixedThreadPool(16);
@GetMapping("/performance")
DeferredResult<String> performanceEndPoint() {
DeferredResult<String> result = new DeferredResult<>();
performancePool.execute(() -> {
try {
Thread.sleep(5000); //A long running task
} catch (InterruptedException e) {
e.printStackTrace();
}
result.setResult("Executed in performance pool");
});
return result;
}
@GetMapping("/normal")
DeferredResult<String> normalEndPoint() {
DeferredResult<String> result = new DeferredResult<>();
normalPool.execute(() -> result.setResult("Executed in normal pool"));
return result;
}
}
You immediately release the Tomcat thread by returning a DeferredResult
from a controller, allowing it to serve other requests. The actual response is written to the user when the .setResult
method is called.
DeferredResult
is one of the many ways you can perform asynchronous request processing in Spring. Check out this section of the docs to learn more about the other ways:
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async