1

我对 Vert.x 很陌生,并且即将举一个小例子,每次当我收到GET对根路径的 -request 时,我都会从某个外部服务器读取当前时间。我认为使用launchandawaitResult将为我处理异步部分,但日志只是告诉我,线程正在阻塞。对外部 url 的请求大约需要 5 到 7 秒。使用更快的 url 是可能的,但我有意使用慢速的 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
4

2 回答 2

0

两个错误:

您的功能不可暂停:

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

于 2018-02-25T19:05:49.877 回答
0

用于awaitBlocking阻止调用,例如您的 URL 获取。

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

于 2019-08-26T01:48:07.013 回答