Vert.x是否支持将异步结果转换为同步结果?

huangapple go评论68阅读模式
英文:

Does Vert.x support the operation of converting asynchronous results to synchronous ones?

问题

I have a method with a synchronous return value, but it internally calls an asynchronous operation.

现在我使用 ".toCompletionStage().toCompletableFuture().get"。但是我遇到了线程阻塞的问题。我很困惑,怀疑与线程池有关。谁可以帮我解释这个问题?

public String load(){
    
     Future<String> future = /* sample code return future*/;
     String data = future.toCompletionStage().toCompletableFuture().get();
     return data;
}
vertx.consumer("topic", req->{
     String data = load();
     req.reply(data);
}

当我请求 "topic" 时,它会阻塞事件循环线程。

英文:

I have a method with a synchronous return value, but it internally calls an asynchronous operation.

Now I use ".toCompletionStage().toCompletableFuture().get". But I have encountered blocked thread problems. I am very confused and suspect it's related to the thread pool. Who can help me explain this?

public String load(){
    
     Future&lt;String&gt; future = /* sample code return future*/;
     String data = future.toCompletionStage().toCompletableFuture().get();
     return data;
}
vertx.consumer(&quot;topic&quot;, req-&gt;{
     String data = load();
     req.reply(data);
}

When I request the "topic", it will block eventloop thread.

答案1

得分: 1

"Converting" a Future would mean to block execution until the result is available. And that's against Vert.x No. 1 rule - never block the event loops.

Reason for this is that an event loop has only one thread to deal all I/O events. If you block it, all other events (requests, file system operations etc.) will need to wait.

That's why vertx-blocked-thread-checker is unhappy and warns you, so you have a chance to fix the issue.

The load method in your example should just return Future&lt;String&gt;. That way, you defer processing of load()'s result until it is available. All calling methods will have to adapt and also work with or return Future. If that seems strange, there are many discussions about function coloring out there...

load() should look like this:

public Future&lt;String&gt; load() {
  return /* sample code return future*/
}

And the call site should look like this:

vertx.consumer(&quot;topic&quot;, req -&gt; {
     load().onSuccess(data -&gt; req.reply(data));
});

Note how the code declares now what needs to be done after the result is available.

英文:

Short answer: No. "Converting" a Future would mean to block execution until the result is available. And that's against Vert.x No. 1 rule - never block the event loops.

Reason for this is that an event loop has only one thread to deal all I/O events. If you block it, all other events (requests, file system operations etc.) will need to wait.

That's why vertx-blocked-thread-checker is unhappy and warns you, so you have a chance to fix the issue.

The load method in your example should just return Future&lt;String&gt;. That way, you defer processing of load()'s result until it is available. All calling methods will have to adapt and also work with or return Future. If that seems strange, there are many discussions about function coloring out there...

load() should look like this:

public Future&lt;String&gt; load() {
  return /* sample code return future*/
}

And the call site should look like this:

vertx.consumer(&quot;topic&quot;, req -&gt; {
     load().onSuccess(data -&gt; req.reply(data));
});

Note how the code declares now what needs to be done after the result is available.

huangapple
  • 本文由 发表于 2023年5月15日 10:12:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76250480.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定