简体   繁体   English

如何同时调用多个 Uni

[英]How to call multiple Uni concurrently

Recently, I'm working on a project where I have 2 make 2 asynchronous calls at the same time.最近,我正在做一个项目,我有 2 个同时进行 2 个异步调用。 Since I'm working with Quarkus, I ended up trying to make use of Mutiny and the vert.x library.由于我正在使用 Quarkus,我最终尝试使用 Mutiny 和 vert.x 库。 However, I can not get my code working with Unis.但是,我无法让我的代码与 Unis 一起使用。 In the below code, I would imagine that both Unis would be called and the Uni that returns fastest would be returned.在下面的代码中,我想两个 Unis 都会被调用,并且返回最快的 Uni 会被返回。 However, it seems that when combining Unis it simply returns the first one in the list, even though the first uni should take a longer time.但是,似乎在组合 Unis 时,它只是返回列表中的第一个,即使第一个 uni 应该花费更长的时间。

The below code prints out one one when it should print out two two since the uniFast should finish first.下面的代码在应该打印出two two时打印出one one ,因为 uniFast 应该首先完成。 How do I combine Unis and have the faster one return first?我如何结合 Unis 并让更快的一个先返回?

@Test
    public void testUniJion(){
        var uniSLow = Uni.createFrom().item(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "one";
        });

        var uniFast = Uni.createFrom().item(() -> {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "two";
        });

        var resp = Uni.join().first(uniSLow,uniFast).withItem().await().indefinitely();
        System.out.println(resp);

        var resp2 = Uni.combine().any().of(uniSLow,uniFast).await().indefinitely();
        System.out.println(resp2);
    }

Note: This is not the actual code I am trying to implement.注意:这不是我要实现的实际代码。 In my code, I am trying to fetch from 2 different databases.在我的代码中,我试图从 2 个不同的数据库中获取。 However, one database often has a lot more latency than the other.但是,一个数据库通常比另一个数据库有更多的延迟。 However, Uni seems to always wait for the slower database.但是,Uni 似乎总是等待较慢的数据库。 I'm simply trying to understand Mutiny and Uni's better so I made this code example.我只是想更好地理解 Mutiny 和 Uni,所以我制作了这个代码示例。

The problem is that you are not telling Mutiny on which thread should run each uni.问题是你没有告诉Mutiny应该在哪个线程上运行每个 uni。 If I add a System.out to your example:如果我将System.out添加到您的示例中:

// Slow and Fast for the different Uni
System.out.println( "Slow - " + Thread.currentThread().getId() + ":" + Thread.currentThread().getName() );

I get the following output:我得到以下输出:

Slow - 1:Test worker
one
Slow - 1:Test worker
Fast - 1:Test worker
one

The output shows that everything runs on the same thread and therefore when we block the first one, the second one is blocked too.输出显示所有东西都在同一个线程上运行,因此当我们阻塞第一个线程时,第二个线程也被阻塞了。 That's why the output is one one .这就是为什么输出是one one的原因。

One way to run the uni in parallel is to use a different executor at subscription:并行运行 uni 的一种方法是在订阅时使用不同的执行器:

ExecutorService executorService = Executors.newFixedThreadPool( 5 );
uniSlow = uniSlow.runSubscriptionOn( executorService );
uniFast = uniFast.runSubscriptionOn( executorService );

Now, when I run the test, I have the expected output:现在,当我运行测试时,我得到了预期的输出:

Slow - 16:pool-3-thread-1
Fast - 17:pool-3-thread-2
two
Slow - 18:pool-3-thread-3
Fast - 19:pool-3-thread-4
two

Note that this time Slow and Fast are running on different threads.请注意,这一次 Slow 和 Fast 运行在不同的线程上。

The Mutiny guide has a section about the difference between emitOn vs. runSubscriptionOn and some examples on how to change the emission thread . Mutiny 指南中有一节介绍了emitOn 与 runSubscriptionOn之间的区别以及一些关于如何更改发射线程的示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM