As I understand it, it is somewhat common practice in API development to return a CompletableFuture as a response type to an API request in situations where the requests could take quite some time to process.
Handing off to ForkJoinPool threads, for example, would be done in order to free up request handling threads that would otherwise be blocked for the full duration of the request, allowing them to continue servicing more requests.
Consider this example:
@GetMapping("/hello-world")
public CompletableFuture<String> helloWorld() {
return CompletableFuture.supplyAsync(() -> {
//take 5 seconds to respond with Hello World
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello World";
});
}
A tomcat request processing thread would handle the request and respond with the CompletableFuture. However, a ForkJoinPool thread would be responsible for handling the processing of the CompletableFuture itself.
From the client's perspective, the request to retrieve the String "Hello World" is 'pending' and then finally resolves after 5 seconds... But the response does indeed contain the String "Hello World".
I was expecting the response to the client to be immediate without the resolved "Hello World" string seeing as the CompletableFuture was returned immediately by the request processing thread.
As I understand it, the request processing thread was released almost immediately. So, How and what is responsible for getting the String "Hello World" back to the client? Is it the ForkJoinPool thread?
There must be some HTTP protocol magic to keep the connection between the client and the server active until the ForkJoinPool thread finally resolves the CompletableFuture?
What am I missing in my understanding... Please learn me in the ways of async programming...