Akka and futures, which ExecutionContext should be used

akkaconcurrencyscala

Following this blog by @Tomasz Nurkiewicz we can see that 4 different approaches are available for picking the ExecutionContext, when interacting with akka actors, for scala futures to run on.

import ExecutionContext.Implicits.global

//or

implicit val ec = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(50))

//or (inside actor)

import context.dispatcher

//or (explicitly)

val future = Future {
    //...
} (ec)

Only one is akka specific, the rest are agnostic to the fact that concurrency is handled by actors, elsewhere.

Given that there are situations where handling concurrency with actors and futures is unavoidable (for example, my question on SO regarding slick), which paradigm would fit best? Running the future on the actor's dispatcher, or one of the other possibilities, as illustrated above?


BTW, rereading my question on SO, I see that I used Scala's global ExecutionContext, yet the logs log the threads handling the future code as belonging to the ActorSystem's default dispatcher… what's going on with that???


EDIT,

went back to the aforementioned SO question and recreated the example. The world makes more sense again, as the following logs appeared (we can see that the default global ForkJoinPool is invoked within the future while the default dispatcher is used for actors):

[INFO] [11/04/2015 09:29:06.267] [wtf-akka.actor.default-dispatcher-3] [akka://wtf/user/$a] ['wtf1] external block pre future
[INFO] [11/04/2015 09:29:06.287] [wtf-akka.actor.default-dispatcher-3] [akka://wtf/user/$a] ['wtf1] external block post future
[INFO] [11/04/2015 09:29:06.287] [ForkJoinPool-2-worker-7] [akka://wtf/user/$a] ['wtf1] internal block pre sleep
[INFO] [11/04/2015 09:29:06.461] [wtf-akka.actor.default-dispatcher-2] [akka://wtf/user/$a] ['wtf2] external block pre future
[INFO] [11/04/2015 09:29:06.471] [wtf-akka.actor.default-dispatcher-2] [akka://wtf/user/$a] ['wtf2] external block post future
[INFO] [11/04/2015 09:29:06.472] [ForkJoinPool-2-worker-5] [akka://wtf/user/$a] ['wtf2] internal block pre sleep

Best Answer

You say to consider Slick as an example. Slick will use JDBC, and thus will use blocking I/O, i.e. the thread will not be available to do other work while it waits for the response from the database. You don't want to use your default Akka dispatcher for that.

You could define a separate execution context for your database operations and use that. I think this documentation page might be helpful for you.

Related Topic