简体   繁体   English

在垂直环境中,是否应该使用vertx ExecutionContext执行Scala未来的完成?

[英]In a verticle, should I use vertx ExecutionContext to execute the completion of a Scala future?

In an attempt to get out of nested callbacks hell, at least for readability, I am using Scala futures in my vertx application. 为了摆脱嵌套回调,至少出于可读性考虑,我在vertx应用程序中使用了Scala Futures。

I have a simple verticle handling HTTP requests. 我有一个简单的Verticle处理HTTP请求。 Upon receiving a request, the verticle calls a method doing async stuff and returning a Future. 收到请求后,顶点将调用一个方法,该方法执行异步操作并返回Future。 On future completion, HTTP response is sent to the client: 在将来完成时,HTTP响应发送到客户端:

class HttpVerticle extends Verticle with VertxAccess {
    val routeMatcher = RouteMatcher()

    routeMatcher.get("/test", request => {      
        println(Thread.currentThread().getName)
        // Using scala default ExecutionContext
        import scala.concurrent.ExecutionContext.Implicits.global

        val future = getTestFilePath()
        future.onComplete {
            case Success(filename) => {
                println(Thread.currentThread().getName)
                request.response().sendFile(filename)
            }
            case Failure(_) => request.response().sendFile("/default.txt")
        }
    })

    def getTestFilePath(): Future[String] = {
        // Some async stuff returning a Future
    }
}

I noticed that using the usual (at least for me) ExecutionContext, the thread executing the completion of the future is not part of the vertx pool (this is what the prinln statement is for). 我注意到,使用通常的(至少对我来说)ExecutionContext,执行将来完成的线程不是顶点池的一部分(这是prinln语句的目的)。 The first prinln outputs vert.x-eventloop-thread-4 whereas the second outputs ForkJoinPool-1-worker-5 . 第一个prinln输出vert.x-eventloop-thread-4而第二个输出ForkJoinPool-1-worker-5

Then, I supposed I had to use instead the vertx execution context: 然后,我以为我不得不使用vertx执行上下文:

class HttpVerticle extends Verticle with VertxAccess {
    val routeMatcher = RouteMatcher()

    routeMatcher.get("/test", request => {      
        println(Thread.currentThread().getName)
        // Using vertx execution context
        implicit val ec: ExecutionContext = VertxExecutionContext.fromVertxAccess(this)

        val future = getTestFilePath()
        future.onComplete {
            case Success(filename) => {
                println(Thread.currentThread().getName)
                request.response().sendFile(filename)
            }
            case Failure(_) => request.response().sendFile("/default.txt")
        }
    })

    def getTestFilePath(): Future[String] = {
        // Some async stuff returning a Future
    }
}

With this, the first and second println will output vert.x-eventloop-thread-4 . 这样,第一和第二个println将输出vert.x-eventloop-thread-4

Note that this is a minimal example. 请注意,这是一个最小的示例。 In my real application code, I have multiple nested callbacks and thus chained futures. 在我的实际应用程序代码中,我有多个嵌套的回调,因此也链接了期货。

My questions are: 我的问题是:

  1. Should I use the vertx execution context with all my futures in verticles ? 我是否应该将vertx执行上下文与所有期货一起使用在verticles中?
  2. Same question for worker verticles. 工人垂直线的相同问题。
  3. If the answers to the above questions are yes, is there a case where, in a vertx application, I should not use the vertx application context ? 如果对以上问题的回答为“是”,那么在vertx应用程序中是否应该不使用vertx应用程序上下文?

Note: I am using vertx 2.1.5 with lang-scala 1.0.0. 注意:我正在将vertx 2.1.5与lang-scala 1.0.0一起使用。

I got an answer from Lars Timm on the vert.x Google user group : 我在vert.x Google用户组上从Lars Timm得到了答案

Yes, you should use the Vertx specific execution context. 是的,您应该使用Vertx特定的执行上下文。 That ensures the futures are run on the correct thread/event loop. 这样可以确保期货在正确的线程/事件循环上运行。 I haven't tried it with worker verticles but I don't see why it shouldn't work there also. 我还没有尝试过使用工人垂直线,但是我不明白为什么它也不能在那里工作。

By the way, you should consider using the 1.0.1-M1 instead of 1.0.0. 顺便说一句,您应该考虑使用1.0.1-M1而不是1.0.0。 As far as I remember an error was fixed in the ExecutionContext in that version. 据我所知,该版本的ExecutionContext中已修复错误。 You also don't have to import the VertxExecutionContext. 您也不必导入VertxExecutionContext。 It's automatically done when you inherit from Verticle/VertxAccess. 从Verticle / VertxAccess继承时,它会自动完成。

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

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