简体   繁体   English

如何在 Vertx 事件循环线程上运行 CompletableFuture 处理程序?

[英]How do I run a CompletableFuture handler on the Vertx event loop thread?

I have a library xyz that gives me a CompletableFuture which I want to process on my Vertx (v3.5) event loop.我有一个库 xyz,它给了我一个 CompletableFuture,我想在我的 Vertx (v3.5) 事件循环中处理它。 Currently I am using CompletableFuture.handle(BiFunction) (see below) but I would like to use CompletableFuture.handleAsync(BiFunction, Executor) , but I cannot figure out how to provide the vertx event loop thread to the second parameter in this method call.目前我正在使用CompletableFuture.handle(BiFunction) (见下文)但我想使用CompletableFuture.handleAsync(BiFunction, Executor) ,但我无法弄清楚如何在此方法调用中将 vertx 事件循环线程提供给第二个参数.

I tried executing this whole code in Vertx.runOnContext() but the calls inside handleAsync still executed on Java's ForkJoin pool which I want to avoid.我尝试在Vertx.runOnContext()中执行整个代码,但 handleAsync 中的调用仍然在我想避免的 Java 的 ForkJoin 池中执行。

CompletableFuture<Void> f = xyz.someMethod();
f.handle((v, th) -> { //Want to run this in handleAsync()
   if (th == null) {
     future.complete(null);
   } else {
     future.completeExceptionally(th);
   }
   return null;
});

You can achieve this by simply using vertx.nettyEventLoopGroup() as the second parameter, so your code will be something like this:您可以通过简单地使用vertx.nettyEventLoopGroup()作为第二个参数来实现这一点,因此您的代码将如下所示:

CompletableFuture<Void> f = xyz.someMethod();
f.handleAsync((v, th) -> { 

  if (th == null) {
    future.complete(null);
  } else {
    future.completeExceptionally(th);
  }

  return null;
}, vertx.nettyEventLoopGroup());

Note: the above code will may run the callback code not on the same thread the Vertx future was running.注意:上面的代码可能会运行回调代码,而不是在 Vertx future 运行的同一线程上。

To preserve the threading model of the Vertx you need to use the following code:要保留 Vertx 的线程模型,您需要使用以下代码:

CompletableFuture<String> f = xyz.someMethod();
Context context = vertx.getOrCreateContext();
f.handleAsync((v, th) -> {
    context.runOnContext(event -> {
        if (th == null) {
            future.complete(null);
        } else {
            future.completeExceptionally(th);
        }
    });
    return null;
});

This can be done the following way.这可以通过以下方式完成。 It is a workaround, not an optimal solution.这是一种解决方法,而不是最佳解决方案。 Initially I placed the runOnContext call outside handle method, which is why it did not work.最初我将 runOnContext 调用放在 handle 方法之外,这就是它不起作用的原因。

CompletableFuture<Void> f = xyz.someMethod(); f.handle((v, th) -> { vertx.runOnContext(e->{ if (th == null) { future.complete(null); } else { future.completeExceptionally(th); } }); return null; });

This will make one extra context switch (from ForkJoin pool to vertx event loop) which is one disadvantage of this approach.这将进行一次额外的上下文切换(从 ForkJoin 池到 vertx 事件循环),这是这种方法的一个缺点。

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

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