读取慢速外部时带有协同程序的 Vertx 块 url

Vertx with coroutines blocks when reading slow external url

我是 Vert.x 的新手,我准备做一个小例子,每次当我收到 GET- 对根的请求时,我都会从一些外部服务器读取当前时间-小路。我以为使用 launchawaitResult 会为我处理异步部分,但日志只是告诉我,线程正在阻塞。向外部 url 的请求大约需要 5 到 7 秒。使用更快的 url 是可能的,但我有意想使用较慢的 Vert.x.

的异步方面的感觉

有人可以帮我吗?我对协同程序做错了什么?

class MainVerticle : CoroutineVerticle() {
    override suspend fun start() {
        val server = vertx.createHttpServer()
        val router = Router.router(vertx)

        router.get("/home").handler { handleGet(it) }

        server.requestHandler {
            router.accept(it)
        }.listen(8080) { }
    }

    private fun handleGet(event: RoutingContext) {
        launch(vertx.dispatcher()) {
            // this request takes about 5 secs the first time
            val url = "my-slow-url"

            val jsonStr = awaitResult<String> { handler ->
                val (_, response) = url.httpGet().responseString()
                val jsonStr = response.data.toString(Charsets.UTF_8)
                handler.handle(Future.succeededFuture(jsonStr))
            }
            ...
        }
    }
}

但这给了我

Feb 22, 2018 10:30:57 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 2025 ms, time limit is 2000
Feb 22, 2018 10:30:58 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 3025 ms, time limit is 2000
Feb 22, 2018 10:30:59 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 4025 ms, time limit is 2000
Feb 22, 2018 10:31:00 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 5026 ms, time limit is 2000
io.vertx.core.VertxException: Thread blocked

两个错误:

您的函数不可暂停:

private fun handleGet(event: RoutingContext) {

然后你在 EventLoop 上调度:

launch(vertx.dispatcher()) {

此外,我不确定您实际上是如何获取 URL 的。我希望它是非阻塞的,然后你可以使用 .await():

http://vertx.io/docs/vertx-lang-kotlin-coroutines/kotlin/#_awaiting_the_completion_of_vert_x_futures

使用 awaitBlocking 来阻止像 URL 提取这样的调用。

awaitResult 是获取一个处理程序,可以用作事件总线等基于回调的函数的语法糖 api。因此,您无需编写回调,而是将您从 awaitResult 获得的处理程序作为参数传递。也就是说,如果您的底层代码正在阻塞 - 将其包装在事件循环中的 awaitResult 中仍然会导致事件循环阻塞