Create a CompletableFuture from a blocking method call… here is a solution to the problem.
Create a CompletableFuture from a blocking method call
How to “transform” a
blocking method call to CompletableFuture ? Example:
T waitForResult() throws InterruptedException {
obj.await(); blocking call
// ...
return something;
}
I need to make it like this :
CompletableFuture.of(this::waitForResult); .of(Callable<T>) doesn't exist
Some things to consider:
waitForResult()
may throw an exception. These must be handled correctly so thatcompletableFuture.get()
throwseither InterruptedException
orExecutionException
.- No other threads must be involved (
supplyAsync()
will do this). - It must be a CompletableFuture (possibly wrapped).
I tried, but this doesn’t handle exceptions correctly :
CompletableFuture.completedFuture(Void.TYPE).thenApply(v -> {
try {
listener.await();
// ...
return listener.getResult();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (SnmpException e) {
throw new RuntimeException(e);
}
});
I know Create CompletableFuture from a sync method call, but that didn’t help me:
- The original code in question blocked the main thread
- The code in the answer either merged the third thread or didn’t handle the exception properly (correct me if I’m wrong).
Solution
I’m not sure I understand your request. Does this meet their requirements?
private <T> CompletableFuture<T> supplySynchronously(Callable<T> callable) {
CompletableFuture<T> f = new CompletableFuture<>();
try {
f.complete(callable.call());
} catch (Exception e) {
f.completeExceptionally(e);
}
return f;
}