I have a function that works on a single element:
Mono<Foo> myFunction(String arg) {
// do shiz
return result;
}
Now, I am trying to reuse the above method to do the same, but for a list of args:
Mono<List<Foo>> myNewFunction(List<String> args) {
Flux.fromIterable(args)
.map(currentArg -> myFunction(currentArg))
.map(Mono::block)
.collectList();
}
But it always fails with the same error:
ava.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-3
...
Error has been observed at the following site(s):
|_ checkpoint ⇢ Handler com.xxx.yyy.zzz.Controller#foo(InputRequest) [DispatcherHandler]
|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ HTTP POST "/v1/my/end/point" [ExceptionHandlingWebHandler]
(A controller is calling the myNewFunction
)
I have verified that myFunction
works when I call it directly from the controller. But when I go through myNewFunction
, it fails.
How do I debug this and fix this? I can't tell what the error is. Thanks
First, Flux
is an asynchronous sequence of 0-N items, while Mono
end with 0-1 result, so your controller shoud return Flux<Foo>
:
Flux<Foo> myNewFunction(List<String> args) {
return Flux.fromIterable(args)
// if myFunction returns Mono, use flatMap instead of map.
.flatMap(currentArg -> myFunction(currentArg));
}
If you want return Mono<List<Foo>>
instead of Flux<Foo>
, use collectList
:
Mono<List<Foo>> myNewFunction(List<String> args) {
return Flux.fromIterable(args)
.flatMap(currentArg -> myFunction(currentArg))
.collectList();
}
Second, blocking operation should not used in non-blocking thread, which cause the error.