My application uses Play framework to process REST requests. I need to perform some potentially long lasting blocking I/O operation in http request handler. In parallel I\'d
I would recommend that you set up your own context and run your blocking/cpu-intensive operations there using Plays F.Promise
. As always with threads, the optimal solution depends on numerous of things like number of cores etc.
First set up your context in applications.conf
:
play {
akka {
akka.loggers = ["akka.event.Logging$DefaultLogger", "akka.event.slf4j.Slf4jLogger"]
loglevel = WARNING
actor {
default-dispatcher = {
fork-join-executor {
parallelism-min = 1
parallelism-factor = 2
parallelism-max = 6
}
}
my-context {
fork-join-executor {
parallelism-min = 1
parallelism-factor = 4
parallelism-max = 16
}
}
}
}
}
Then in your controller, make use of your context using Plays Promises (I'm using Java 8):
public static F.Promise love() {
ExecutionContext myExecutionContext = Akka.system().dispatchers().lookup("play.akka.actor.my-context");
F.Promise integerPromise = F.Promise.promise(() ->
LongRunningProcess.run(10000L)
, myExecutionContext);
F.Promise integerPromise2 = F.Promise.promise(() ->
LongRunningProcess.run(10000L)
, myExecutionContext);
return integerPromise.flatMap(i -> integerPromise2.map(x -> ok()));
}
This way your Play app will still handle short lasting requests on the default-dispatcher
execution context and the blocking/cpu-intensive will run in my-context
.
I made a very short example for you demonstrating this, check it out on github.