Concurrency in Play 2.1 or above
Asked Answered
J

2

6

I've read a few tutorials on how to deal with concurrency in Play and found some examples:

Asynchronous Job

import scala.concurrent.{ExecutionContext, future}

def sendEmailAsync(from: String, to: String, subject: String, body: String) = {
  import ExecutionContext.Implicits.global // in scala.concurrent

  future {
    EmailHelper.sendEmail(from, to, subject, body)
  }
}

Scheduled Job

import play.api.libs.concurrent.{Akka, Execution}

def sendEmailOnSchedule(from: String, to: String, subject: String, body: String) = {
  import scala.concurrent.duration._
  import Execution.Implicits.defaultContext // in play.api.libs.concurrent

  Akka.system.scheduler.scheduleOnce(10 seconds) {
    EmailHelper.sendEmail(from, to, subject, body)
  }
}

Well, I'm a bit confused... the first example uses scala.concurrent.ExecutionContext.Implicits.global while the second example uses play.api.libs.concurrent.Execution.Implicits.defaultContext. Why? Could someone explain me what is going on behind the scene?

Johannessen answered 16/12, 2013 at 21:36 Comment(1)
The ExecutingContext was something like java's ExecutorService(Thread Pool), you can even create it yourself if you like. For example, play-slick module use a separated context to execution db operations. github.com/freekh/play-slick/blob/master/src/main/scala/play/…Lawlor
U
3

Scala uses an ExecutionContext for some asynchronous things (Futures, Promises). An ExecutionContext can be thought of like a Thread Pool, in which Runnables can be submitted to be run on one of the threads. (It isn't necessarily always a thread pool, but it tends to be).

The way the ExecutionContext is used is usually to pass it in as an implicit argument to the function that would use it. You'll often see method signatures like this:

def doAsyncThings(args: Args)(implicit exc: ExecutionContext): Future[Result]

The "doAsyncThings" method will use the implicit exc that gets passed in to put work onto a separate thread.

To answer your question, the Implicits imports from the two examples are implicit ExecutionContext instances, which are needed to call the future and scheduleOnce methods. For exploratory purposes, it doesn't matter which one you use. The global one from the scala library contains (iirc) a thread pool with 8 or so threads. I would guess that the play one is similar. Unless you are being extra-careful about which threads do what work, the choice should not affect you.

Unfriended answered 16/12, 2013 at 23:1 Comment(0)
C
-2

I would guess the difference comes from "10 seconds". the ability to literally name times like is not built into the language. "seconds" is implicitly converted to DurationInt.

Coagulum answered 17/12, 2013 at 22:51 Comment(1)
This has nothing to do with the dispatcher, it comes from the scala.concurrent.duration._ import.Headwork

© 2022 - 2024 — McMap. All rights reserved.