How does the execution context from
import scala.concurrent.ExecutionContext.Implicits.global
differ from Play's execution contexts:
import play.core.Execution.Implicits.{internalContext, defaultContext}
How does the execution context from
import scala.concurrent.ExecutionContext.Implicits.global
differ from Play's execution contexts:
import play.core.Execution.Implicits.{internalContext, defaultContext}
They are very different.
In Play 2.3.x and prior, play.core.Execution.Implicits.internalContext
is a ForkJoinPool
with fixed constraints on size, used internally by Play. You should never use it for your application code. From the docs:
Play Internal Thread Pool - This is used internally by Play. No application code should ever be executed by a thread in this thread pool, and no blocking should ever be done in this thread pool. Its size can be configured by setting internal-threadpool-size in application.conf, and it defaults to the number of available processors.
Instead, you would use play.api.libs.concurrent.Execution.Implicits.defaultContext
, which uses an ActorSystem
.
In 2.4.x, they both use the same ActorSystem
. This means that Akka will distribute work among its own pool of threads, but in a way that is invisible to you (other than configuration). Several Akka actors can share the same thread.
scala.concurrent.ExecutionContext.Implicits.global
is an ExecutionContext
defined in the Scala standard library. It is a special ForkJoinPool
that using the blocking
method to handle potentially blocking code in order to spawn new threads in the pool. You really shouldn't use this in a Play application, as Play will have no control over it. It also has the potential to spawn a lot of threads and use a ton of memory, if you're not careful.
I've written more about scala.concurrent.ExecutionContext.Implicits.global
in this answer.
They are the same and point out to the default dispatcher of the underlying actor system in your Play or Akka or combined application.
play.api.libs.concurrent.Execution.Implicits.defaultContext
play.core.Execution.Implicits.internalContext
class ClassA @Inject()(config: Configuration)
(implicit ec: ExecutionContext) {
...
}
But this is different:
scala.concurrent.ExecutionContext.Implicits.global
Also DB drivers, e.g. if you use slick, may come up with their own Execution Context. Anyway,
scala.concurrent.ExecutionContext.Implicits.global
, when you are in play or akka framework, in this way you may use more threads than optimum during high load so the performance may decrease.scala.concurrent.ExecutionContext.Implicits.global
when you have no other executor running in your app. Don’t worry this is safe then.Await
for a futureapplication.conf