Reputation: 5052
Small question regarding how to return the result of a subscribe please.
Setup, I have a piece of code that is run in a mono core environment, no possibility of high concurrency.
I need to make a http call to a server, that will take 10 seconds (always) to process the request and return the response.
Therefore, using Spring Webflux WebClient, I first went with:
final String response = webClient.post().uri("https://api-that-will-take-ten-seconds.com/slow").body(BodyInserters.fromValue(someRequests)).retrieve().bodyToMono(String.class).block();
if (someCondition(response)) {
System.out.println("condition met");
return response;
} else {
System.out.println("condition not met");
return "bad";
}
});
And this worked, unfortunately, very very slow. This got called with 1000 someRequests, and I could see one log line printed every 10 seconds, the server also confirm they only received one request every 10 seconds.
Since it is super slow, I changed into a fire and forget solution, as follow:
webClient.post().uri("https://api-that-will-take-ten-seconds.com/slow").body(BodyInserters.fromValue(someRequests)).retrieve()
.bodyToMono(Void.class)
.subscribe();
System.out.println("no response at all, don't know if condition met");
return "no response at all";
And it worked, but it worked too well. The 1000 someRequests came, I sent all of them to the server, who confirm could see everything arrived almost "in one go".
Unfortunately, on my side, the program also finished super quick, too quick, as only couple of "no response at all, don't know if condition met" got printed, and the program finished.
May I ask if there is a middle ground, where I can avoid doing all those long processing one by one, but not at a point where a send everything, and cannot even see all the responses please?
I tried something like:
final Mono<String> response = webClient.post().uri("https://api-that-will-take-ten-seconds.com/slow").body(BodyInserters.fromValue(someRequests)).retrieve().bodyToMono(String.class)
.subscribe(res -> {
if (someCondition(res)) {
System.out.println("condition met");
//return condition met;
} else {
System.out.println("condition not met");
//return condition not met;
}
});
return "it finishes, but I do not know if condition met";
Here, I do see some logs being printed, the server received everything very quick, but I cannot return if the condition is met or not.
Thank you!
Upvotes: 1
Views: 9666
Reputation: 14792
using a Flux
and flatMap
will do all requests async, then you collectList and block to get the list of strings.
List<Strings> strings = Flux.fromIterable(dataList)
.flatMap(data -> webclient.post( ... )
.bodyValue(data)
.retreive()
.bodyToMono(String.class))
.collectList()
.block();
Upvotes: 2