0

I'm relatively new to reactive programming. My question is regarding Mono::then

What I want to do is, extract the body from incoming request, set it to a static variable. Once that is done, send a response saying that the service has started. But the following code always returns "Service started for: null".

I thought Mono::then should run after the first mono completes(in this case, after setting the static variable) and return "Service started for: a,b,c".

Is my understanding wrong?

(Also, any code criticism is appreciated)

public Mono<ServerResponse> getStatus(ServerRequest req) {
        Mono<List<Request>> body = req.bodyToFlux(Request.class).collectList();
        return ServerResponse.ok()
                .body(body.doOnNext(i -> {
                    Service.a = i;
                    logger.info("Service started for : {}", i.toString());
                })


                        .then(Mono.just("Service started for: " + Service.a)), String.class);
    }
Martin Tarjányi
  • 8,863
  • 2
  • 31
  • 49
Alcanzer
  • 57
  • 11
  • "Mono::then should run after" There is nothing to run. Mono::just javadoc: "Create a new Mono that emits the specified item, which is captured at instantiation time." You can check your assumptions about Mono::then using Mono::fromCallable, Mono::fromSupplier instead of Mono::just – Vlad Mamaev Feb 13 '20 at 21:56
  • Shouldn't Mono::just run "after" body.doOnNext? – Alcanzer Feb 13 '20 at 22:04

1 Answers1

1

Communicating through static variables are very discouraged (especially in functional and reactive programming). As in your question you didn't provide enough information about the Service you start, it's a bit difficult to recommend.

However, based on the available information, I would start out with something like this:

public Mono<ServerResponse> getStatus(ServerRequest req) {
    return req.bodyToFlux(Request.class)
            .collectList()
            .doOnNext(requestBody -> System.out.println("Do your service start here in the background."))
            .flatMap(requestBody -> ServerResponse.ok().syncBody("Service started for: " + requestBody));
}
Martin Tarjányi
  • 8,863
  • 2
  • 31
  • 49
  • Thanks Martin for the response. I've since made changes and no longer use static variables.I was wondering why `Mono::then` wasn't working as expected. My understanding is that it should wait till the previous Mono ends and then emit the mono in then(). – Alcanzer Feb 15 '20 at 16:58
  • 1
    It is because the string inside is getting evaluated eagerly before the first part of the flow is executed, details: https://stackoverflow.com/a/57877616/6051176 As another commenter suggested, you can use Mono::fromSupplier to overcome this issue. – Martin Tarjányi Feb 15 '20 at 20:53
  • **It is because the string inside is getting evaluated eagerly before the first part of the flow is executed** makes sense. Thank you for the explanation. Can consider this as closed. – Alcanzer Feb 16 '20 at 18:21