Java 9: Handle timeouts asynchronously using CompletableFuture's orTimeout and completeOnTimeout
When writing asynchronous code using CompletableFuture you can quickly end up in a scenario where you can't wait for a given task to finish. You simply need to timeout and move on.
This is something that has been addressed in Java 9 by introducing two new functions —
Consider the following scenario
Say we've started using the
CompletableFuture API in a system that fetches articles. We're happy with the code except for one ting — we got some issues with a really slow call to the service that fetches the articles.
Timeout a CompletableFuture with an Exception using
One way to address this is to use the
orTimeout does is to complete the CompletableFuture exceptionally if it doesn't complete by itself.
CompletableFuture.supplyAsync(this::getArticles) .orTimeout(1, TimeUnit.MINUTES); // > ExecutionException: java.util.concurrent.TimeoutException
As you can see, all you need to provide is how long you're willing to wait before the timeout should occur.
In our example we use 1 minute, but you can use any time unit — everything from
Timeout a CompletableFuture and provide another value using
Another option is to timeout by providing an alternative value.
You always have to consider what you need, but this variant is probably my favourite.
The thing is, when you compose functions in the way that
CompletableFuture encourages you to do, you can use default values like this to make the system more fault tolerant instead of just failing exceptionally.
In our example, say we got a set of backup articles that we want to display instead of just failing if the
getArticles method doesn't return in time.
Then we can use the
completeOnTimeout method to return our backup articles.
CompletableFuture.supplyAsync(this::getArticles) .completeOnTimeout(getBackupArticles(),1, TimeUnit.SECONDS);
That's it. All we do is to provide the list of backup articles and how long we're willing to wait for the original articles before we timeout and return the backup articles instead.