Search code examples
javaasynchronousquarkusmutiny

Cannot execute job asynchronously


I have a very confusing issue. I'm combining several Uni<Integer> which takes 4, 6, and 8 seconds respectively. I was expecting them to be executed asynchronously, which means it should only take 8 seconds (the longest) in total. However, when I run the code its taking 18 (4 + 6 + 8) seconds to finish.

Where did I go wrong?

My code:

public Uni<Integer> asyncTask(int idx, int delay) {
    return Uni.createFrom().item(Unchecked.supplier(() -> {
        // Perform your asynchronous operation here
        // Simulate a delay
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(new Date() + " " + delay);
        return idx; // Example result
    }));
}

public void executeAsyncTasks() {
    Date startTime = new Date();
    Uni.combine().all()
            .unis(asyncTask(1, 4000), asyncTask(2, 6000), asyncTask(3, 8000))
            .asTuple()

            // Subscribe (which will trigger the calls)
            .subscribe().with(tuple -> {
                System.out.println("item 1: " + tuple.getItem1());
                System.out.println("item 2: " + tuple.getItem2());
                System.out.println("item 3: " + tuple.getItem3());
                Date finishTime = new Date();
                System.out.println(finishTime.getTime() - startTime.getTime());
            });
}

Solution

  • You don't want these tasks to be executed asynchronously. You want them to be executed concurrently. In Quarkus, there are 2 ways how to run multiple tasks concurrently:

    • use non-blocking programming, where multiple tasks execute concurrently on a single thread, because they interleave
    • use threads, where each task runs on its own thread

    You clearly don't use non-blocking programming, because you're blocking (Thread.sleep()).

    You also don't use multiple threads. You may expect Mutiny to create one thread for each task, but that's not how reactive programming libraries work. You'd have to ask for that explicitly.