在 Verticle 中,我应该使用 vertx ExecutionContext 来执行 Scala 未来的完成吗?
In a verticle, should I use vertx ExecutionContext to execute the completion of a Scala future?
为了摆脱嵌套回调地狱,至少为了可读性,我在我的 vertx 应用程序中使用 Scala futures。
我有一个简单的 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,执行 future 完成的线程不是 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
。
请注意,这是一个最小的示例。在我的实际应用程序代码中,我有多个嵌套回调,因此链接了期货。
我的问题是:
- 我应该将 vertx 执行上下文与我在 verticles 中的所有 futures 一起使用吗?
- worker verticles 的相同问题。
- 如果以上问题的答案是肯定的,在 vertx 应用程序中,是否存在我不应该使用 vertx 应用程序上下文的情况?
注意:我使用的是 vertx 2.1.5 和 lang-scala 1.0.0。
我从 vert.x Google 用户组的 Lars Timm 那里得到了一个 answer:
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.
为了摆脱嵌套回调地狱,至少为了可读性,我在我的 vertx 应用程序中使用 Scala futures。
我有一个简单的 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,执行 future 完成的线程不是 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
。
请注意,这是一个最小的示例。在我的实际应用程序代码中,我有多个嵌套回调,因此链接了期货。
我的问题是:
- 我应该将 vertx 执行上下文与我在 verticles 中的所有 futures 一起使用吗?
- worker verticles 的相同问题。
- 如果以上问题的答案是肯定的,在 vertx 应用程序中,是否存在我不应该使用 vertx 应用程序上下文的情况?
注意:我使用的是 vertx 2.1.5 和 lang-scala 1.0.0。
我从 vert.x Google 用户组的 Lars Timm 那里得到了一个 answer:
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.