javaasynchronousreactive-programmingquarkusmutiny

How does Uni<T> works in Quarkus


I am trying to understand the behavior of Uni in Quarkus framework, after checking out their official tutorial getting started with async guide. In the service method I have made the following changes

package org.acme.getting.started.async;

import javax.enterprise.context.ApplicationScoped;

import io.smallrye.mutiny.Uni;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


@ApplicationScoped
public class GreetingService {

    ExecutorService executor = Executors.newFixedThreadPool(10, r -> {
        return new Thread(r, "CUSTOM_TASK_EXECUTION_THREAD");
    });


    public Uni<String> greeting(String name) {
        System.out.println("greeting Executing on Thread "+Thread.currentThread().getName());
        return Uni.createFrom().item(ioSimulation(name))
                .emitOn(executor);//Infrastructure.getDefaultExecutor()
    }

    public String ioSimulation(String param){
        System.out.println("ioSimulation Executing on Thread "+Thread.currentThread().getName());
        try {
            Thread.sleep(8000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello "+param;

    }

}

Then I have tested the /greeting/{name} resource, the execution was not async at all, in fact it executed all related methods within the same thread and in synchronous manner.

then what would be the difference between

@GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/greeting/{name}")
    public Uni<String> greeting(@PathParam String name) {
    }

and

@GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/greeting/{name}")
    public String greeting(@PathParam String name) {
    }

and how is it asynchronous? please help me to understand it.


Solution

  • The problem is in Uni.createFrom().item(ioSimulation(name)). You synchronously call ioSimulation before the Uni is created.

    You should at least use the Supplier variant: Uni.createFrom().item(() -> ioSimulation(name)). That should help.