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

193 skatījumi
Pāriet uz pirmo nelasīto ziņojumu

bbo...@xebia.fr

nelasīta,
2015. gada 21. maijs 04:30:3521.05.15
uz ve...@googlegroups.com
Hello Everyone

First, as this is my first post here, I would like to thank you all for all the informations I found in this Google group. It helped me a lot to understand vertx since I started using it a few month ago.

Now, the question :)
(I posted it a few days ago on Stack Overflow, but got no answers. Seems like this group is much more active.)

In an attempt to get out of nested callbacks hell, at least for readability, I am using Scala futures in my vertx application.

I have a simple verticle handling HTTP requests. Upon receiving a request, the verticle calls a method doing async stuff and returning a Future. On future completion, HTTP response is sent to the client:

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 (i.e. scala.concurrent.ExecutionContext.Implicits.global), the thread executing the completion of the future is not part of the vertx pool (this is what the prinln statement is for). The first prinln outputs vert.x-eventloop-thread-4 whereas the second outputs ForkJoinPool-1-worker-5.

Then, I supposed I had to use instead the vertx execution context:

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.

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 ?
  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 ?

Note: I am using vertx 2.1.5 with lang-scala 1.0.0.


Lars Timm

nelasīta,
2015. gada 21. maijs 11:10:3321.05.15
uz ve...@googlegroups.com
Hi and welcome :-)

Yes, you should use the Vertx specific execution context. 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. As far as I remember an error was fixed in the ExecutionContext in that version.
You also don't have to import the VertxExecutionContext. It's automatically done when you inherit from Verticle/VertxAccess.

Best regards
Lars

Lars Timm

nelasīta,
2015. gada 21. maijs 11:12:5421.05.15
uz ve...@googlegroups.com

bbo...@xebia.fr

nelasīta,
2015. gada 22. maijs 11:46:5622.05.15
uz ve...@googlegroups.com
Hi

Thanks for your prompt answer !

The change you linked is indeed relevant, but the '1.0.1-M1' does not sound like a stable version ready for production code :). According to that, is my way of getting the Vert.x execution context correct ?

Thanks a lot !
Atbildēt visiem
Atbildēt autoram
Pārsūtīt
0 jauni ziņojumi