oo_*_*_oo 13 java multithreading asynchronous playframework-2.0
我的应用程序使用Play框架来处理REST请求.我需要在http请求处理程序中执行一些可能持久的阻塞I/O操作.与此同时,我希望有效地处理一些持久的请求.
如下所述:
http://www.playframework.com/documentation/2.2.0/JavaAsync
持久的操作可以异步运行.另一方面,如下所述:
http://www.playframework.com/documentation/2.2.x/ThreadPools
Play框架使用相同的默认线程池,其中执行所有应用程序代码.至少在Java api中,不可能在不同的线程池上运行异步工作.
因此,我的问题是,是否值得以异步方式运行可能阻塞的I/O操作,考虑到这样的操作无论如何都使用相同的线程池这一事实.或者也许最好增加默认的线程池大小,在这种情况下不要打扰async api?(这样至少代码可读性会高得多)
Fra*_*anz 22
我建议您设置自己的上下文并使用Plays在那里运行阻塞/ cpu密集型操作F.Promise<A>.与线程一样,最佳解决方案取决于许多内容,例如内核数量等.
首先在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
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的控制器中,使用Plays Promises(我正在使用Java 8)来利用你的上下文:
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()));
}
Run Code Online (Sandbox Code Playgroud)
这样,您的Play应用程序仍将处理default-dispatcher执行上下文中的持久请求,并且阻塞/ cpu密集将运行my-context.
我为你演示了一个非常简短的例子,请在github上查看.