In Java, the playback framework handles and blocks I / O asynchronously
My application uses the play framework to handle rest requests I need to perform some potentially persistent blocking I / O operations in the HTTP request handler In parallel, I want to effectively handle some transient persistence requests
As follows:
http://www.playframework.com/documentation/2.2.0/JavaAsync
Persistent operations can run asynchronously On the other hand, as follows:
http://www.playframework.com/documentation/2.2.x/ThreadPools
The play framework uses the same default thread pool in which all application code is executed At least in the Java API, it is impossible to run asynchronous work on different thread pools
So my question is, if it's worth running potentially blocking I / O operations asynchronously, consider the fact that such an operation uses the same thread pool Or maybe it's best to increase the default thread pool size, in which case don't disturb the async API? (at least the code will be much more readable)
Solution
I suggest you set your own context and run your blocking / CPU intensive operations using plays f.promise & a > Like threads, the optimal solution depends on many kernels and so on
First, in applications Set your context in 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 the controller, use play promises (I use Java 8) to use your context:
public static F.Promise<Result> love() { ExecutionContext myExecutionContext = Akka.system().dispatchers().lookup("play.akka.actor.my-context"); F.Promise<Integer> integerPromise = F.Promise.promise(() -> LongRunningProcess.run(10000L),myExecutionContext); F.Promise<Integer> integerPromise2 = F.Promise.promise(() -> LongRunningProcess.run(10000L),myExecutionContext); return integerPromise.flatMap(i -> integerPromise2.map(x -> ok())); }
In this way, your play application will still handle transient persistent requests in the default scheduler execution context, and block / CPU intensive will run in my context
I have demonstrated a very simple example for you. Please check GitHub