'Why is Mutiny call method blocking

just get started with Mutiny, working through the guides (https://smallrye.io/smallrye-mutiny/guides). And as far as I read in the docs, the call method is async (https://smallrye.io/smallrye-mutiny/getting-started/observing-events).

However, with a small snippet it turns out that call method is blocking execution, so is not async from my understanding. Where is the mistake/misunderstanding here?

Uni.createFrom().item("bla")
      .onItem().invoke(i -> LOG.info("before call"))
      .onItem().call(i -> {
          try {
            Thread.sleep(3000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          return Uni.createFrom().voidItem();
        }
      )
      .subscribe().with(i -> LOG.info("after call process. result=" + i));

Log output

11:40:11.026 INFO [main] ....mutiny.vertx.HelloUni - before call
11:40:16.032 INFO [main] ....mutiny.vertx.HelloUni - after call process. result=bla


Solution 1:[1]

Each subscriber (here we have 1 subscriber from main thread) will attempt (separately) to resolve the Uni. When it reaches the call lambda it simply blocks in the Thread.sleep call before creating the new Uni in the chain.

The functions passed to .call or .transformToUni are not supposed to block for I/O inside (sleep is doing that), but instead to initiate an I/O request and immediately return a Uni.

By the way, if we wanted to issue a delay (non-blocking), we could do something like:

Uni<String> uni1 = Uni.createFrom().item("bla")
        .onItem().invoke(s -> logger.info("before call"))
        .onItem().delayIt().by(Duration.ofSeconds(3));

uni1.subscribe().with(s -> logger.info("after: result=" + s));
logger.info("main continues its work ...");
...

Solution 2:[2]

This is because does not auto-magically make your code asynchronous.

Here you block the thread before returning a Uni, so it is totally expected that you observe such a behaviour when you subscribe.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Michail Alexakis
Solution 2 jponge