Play的执行上下文vs scala全局

时间:2015-06-12 14:20:17

标签: scala playframework

执行上下文如何来自

import scala.concurrent.ExecutionContext.Implicits.global

与Play的执行上下文不同:

import play.core.Execution.Implicits.{internalContext, defaultContext}

2 个答案:

答案 0 :(得分:42)

他们非常不同。

在Play 2.3.x及之前版本中,play.core.Execution.Implicits.internalContext是一个ForkJoinPool,其大小受到固定限制,由Play内部使用。您永远不应该将它用于您的应用程序代码。来自文档:

  

播放内部线程池 - 这由Play内部使用。此线程池中的线程不应执行任何应用程序代码,并且不应在此线程池中执行任何阻止。可以通过在application.conf中设置internal-threadpool-size来配置它的大小,它默认为可用处理器的数量。

相反,您可以使用play.api.libs.concurrent.Execution.Implicits.defaultContext,它使用ActorSystem

在2.4.x中,它们都使用相同的ActorSystem。这意味着Akka将在其自己的线程池中分配工作,但是以一种对您来说不可见的方式(除了配置)。几个Akka演员可以共享同一个帖子。

scala.concurrent.ExecutionContext.Implicits.global是Scala标准库中定义的ExecutionContext。这是一个特殊的ForkJoinPool,使用blocking方法处理可能阻塞的代码,以便在池中生成新线程。你真的不应该在Play应用程序中使用它,因为Play无法控制它。它还有可能产生很多线程并使用大量内存,如果你不小心的话。

我已在this answer中详细了解scala.concurrent.ExecutionContext.Implicits.global

答案 1 :(得分:7)

它们是相同的,并指出您的基础actor系统的默认调度程序 播放或Akka或联合申请。

默认播放的上下文

play.api.libs.concurrent.Execution.Implicits.defaultContext

播放内部背景

play.core.Execution.Implicits.internalContext

Guice的EC注入

class ClassA @Inject()(config: Configuration)
                           (implicit ec: ExecutionContext) {
...
}

但这不同

scala.concurrent.ExecutionContext.Implicits.global

DB驱动程序,例如如果你使用光滑,可能会想出自己的执行上下文。无论如何,

最佳实践:

  • 当你在游戏或akka框架中时,不要使用scala.concurrent.ExecutionContext.Implicits.global,这样你在高负荷时可能会使用比最佳线程更多的线程,因此性能可能会降低。
  • 不要害怕!除非你做一些阻塞任务,例如监听网络连接,或明确地从db中读取,使你“当前threed”等待结果,否则尽可能多地使用默认调度程序。
  • 从默认执行程序开始,如果您发现Play / Akka在高负载期间响应不佳,请切换到新的线程池以进行耗时的计算任务。
    • 长时间的计算任务通常不被视为阻塞。例如,遍历内存中的自动完成树。但是,如果您希望在完成计算任务后让控制结构保持正常运行,则可能会认为它们已阻塞。
    • 当您将计算任务视为非阻塞时可能发生的坏事是,当所有线程都在高负载计算时,播放和Akka消息调度程序将暂停。单独的调度程序的优点是队列处理器不会饿死。具有单独调度程序的缺点是您可以分配更多最佳的线程,并且您的整体性能将会降低。
    • 区别在于高负载服务器,不用担心小项目,使用默认
  • 当您的应用中没有其他执行程序运行时,请使用scala.concurrent.ExecutionContext.Implicits.global。不要担心这是安全的。
  • 创建期货后,使用默认池,这是最安全的方式,除非您确定未来是阻止的。然后使用单独的池或尽可能使用blocking {}结构。
  • 创建一个单独的线程池
    • Await未来
    • 您调用Thread.sleep
    • 您正在阅读流/套接字/ http呼叫
    • 使用阻止驱动程序手动查询数据库(通常是光滑的是安全的)
    • 安排要在10秒内运行的任务
    • 安排每秒运行的任务
  • 对于未来的地图/恢复操作,请使用默认执行程序,通常这是安全的
  • 使用默认调度程序进行异常处理是安全的
  • 始终在播放 Akka 中使用 Akka 调度程序,有一种很好的方法可以在application.conf中定义新的调度程序