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