为了摆脱嵌套的回调地狱,至少为了便于阅读,我在我的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。