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
31 Answer
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.