Issue
From the Official Documentation of Mono#block() it is said that:
Subscribe to this Mono and block indefinitely until a next signal is received. Returns that value, or null if the Mono completes empty. In case the Mono errors, the original exception is thrown (wrapped in a RuntimeException if it was a checked exception).
So it is sure that block() method is blocking and it will not execute the next line untill block()
resolved.
But my confusion is while I was using toFuture()
expecting it will be non-blocking but it is behaving exactly like block
method. And in the Documentation of Mono#toFuture() it is stated:
Transform this Mono into a CompletableFuture completing on onNext or onComplete and failing on onError.
Not much clear. Nowhere in this doc said Mono#toFuture()
is blocking.
- Please confirm me if
toFuture()
method blocking or non-blocking? - Also If it is non-blocking then, which thread will responsible to execute the code inside
CompletableFuture
?
Update: added code snippet
using Mono.block()
method:
long time = System.currentTimeMillis();
String block = Mono.fromCallable(() -> {
logger.debug("inside in fromCallable() block()");
//Upstream httpcall with apache httpClient().
// which takes atleast 1sec to complete.
return "Http response as string";
}).block();
logger.info("total time needed {}", (System.currentTimeMillis()-time));
return CompletableFuture.completedFuture(block);
Using Mono.ToFuture()
method:
long time = System.currentTimeMillis();
CompletableFuture<String> toFuture = Mono.fromCallable(() -> {
logger.debug("inside in fromCallable() block()");
//Upstream httpcall with apache httpClient().
// which takes atleast 1sec to complete.
return "Http response as string";
}).toFuture();
logger.info("total time needed {}", (System.currentTimeMillis()-time));
return toFuture;
these two code snippets behaves exactly same.
Solution
Yes, your doubt is absolutely correct. Actually, Mono.block()
and Mono.toFuture()
subscribes immediately and brings you out of the reactive system.
This official Spring blog post will make it more clear for you.
I would also recommend going through the source code of Mono
which shows block
& toFuture
subscribing immediately.
Explanation to @ruhul's first comment
The line where your put .toFuture()
after your sequence makes the code blocking.
So, in the code below
Mono.fromCallable(() -> {
logger.debug("inside in fromCallable() block()");
//Upstream httpcall with apache httpClient().
// which takes atleast 1sec to complete.
return "Http response as string";
}).toFuture(); // this line is the blocking code.
as soon as you confront toFuture()
, the subscription of the sequence begins and your code comes out of the reactive context.
Answered By - 2280259
Answer Checked By - Willingham (JavaFixing Volunteer)