爲了擺脫嵌套的回調地獄,至少爲了便於閱讀,我在我的vertx應用程序中使用了Scala期貨。在Verticle中,我應該使用vertx ExecutionContext來執行Scala未來的完成嗎?
我有一個簡單的verticle處理HTTP請求。在收到請求後,Verticle會調用一個做異步的方法並返回Future。在未來完成後,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
}
}
我注意到,使用通常(至少對我來說)的ExecutionContext,執行以後完成的線程不是vertx池的一部分(此是prinln聲明是什麼)。第一個prinln輸出vert.x-eventloop-thread-4
而第二個輸出ForkJoinPool-1-worker-5
。
然後,我認爲我不得不改用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
}
}
這樣,第一和第二的println將輸出vert.x-eventloop-thread-4
。
請注意,這是一個最小的例子。在我真正的應用程序代碼中,我有多個嵌套回調,因此鏈接了期貨。
我的問題是:
- 我應該用我的verticles所有期貨vertx執行上下文?
- 同一問題的工人垂直。
- 如果上述問題的答案是肯定的,那麼在vertx應用程序中,我是否應該不使用vertx應用程序上下文?
注:我使用的是vertex 2.1.5和lang-scala 1.0.0。