Ответ 1
Я бы рекомендовал вам настроить свой собственный контекст и запустить интенсивные операции блокировки/процессора, используя Plays 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
}
}
}
}
}
Затем в вашем контроллере используйте свой контекст, используя 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()));
}
Таким образом, ваше приложение Play по-прежнему будет обрабатывать короткие длительные запросы в контексте выполнения default-dispatcher
, а интенсивность блокировки /cpu будет работать в my-context
.
Я сделал очень короткий пример, чтобы продемонстрировать это, проверьте его на github.