2

I build the reactive pipeline like this on netty server with spring web-flux:

someService.getSettings(key) //Mono<Settings>
        .filter(Settings::isEnabled)
        .switchIfEmpty(Mono.error(
            new Exception("Setting is disabled.")
        )).then(/*Mono representing API fetch*/ someApi.fetch(param));

As per my understanding, whenever the Settings::isEnabled would return false, the pipeline would be empty and I will get a Mono representing error. However, this behavior does not happens. My someApi.fetch(param) call always fires without the filter Mono being completed. So even if Settings::isEnabled is false or true, someApi.fetch(param) is always fired without completion of Mono.filter.

How do I make sure that error is thrown if filter returns empty Mono and the fetch call happens only when I have checked that the setting is not disabled?

Madeyedexter
  • 1,155
  • 2
  • 17
  • 33
  • your issue is very similar to the following: https://stackoverflow.com/questions/57870706/whats-the-point-of-switchifempty-getting-evaluated-eagerly/57877616#57877616 except, in your case then is evaluated eagerly instead of switchIfEmpty – Martin Tarjányi Feb 05 '20 at 22:17
  • What do you want to achieve by calling to someApi.fetch(param)? Does it return something? You may want to do something like .switchIfEmpty(...).flatMap(settings -> someApi.fetch(settings.getParam())) – Eduard Feb 06 '20 at 12:19
  • 1
    someApi.fetch(param) is always fired because .then(mono) ignores the previous Mono and returns the mono from the parameter. From docs: https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#then-reactor.core.publisher.Mono- Let this Mono complete then play another Mono. In other words ignore element from this Mono and transform its completion signal into the emission and completion signal of a provided Mono. – Eduard Feb 06 '20 at 12:24

1 Answers1

1

this is still java: this call to someApi.fetch(param) is not done inside a lambda, so it can't be lazy. the moment the execution reaches the then line, your fetch method is called. the Flux.defer operator is tailor-made to wrap that call and make it lazy.

Simon Baslé
  • 27,105
  • 5
  • 69
  • 70