玩框架异步处理和阻塞I / O在Java中 [英] Play framework async processing and blocking I/O in Java

查看:160
本文介绍了玩框架异步处理和阻塞I / O在Java中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序使用播放框架来处理REST请求。我需要执行一些潜在的持久阻塞I / O的HTTP请求处理程序操作。与此同时,我想有效地处理一些持续时间短的请求。

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 like to handle efficiently some short lasting requests.

如这里所描述

<一个href=\"http://www.playframework.com/documentation/2.2.0/JavaAsync\">http://www.playframework.com/documentation/2.2.0/JavaAsync

持久的操作可以异步运行。另一方面,如下所述:

long lasting operation can be run asynchronously. On the other hand, as described here:

<一个href=\"http://www.playframework.com/documentation/2.2.x/ThreadPools\">http://www.playframework.com/documentation/2.2.x/ThreadPools

播放框架使用相同的默认线程池,在其中执行所有的应用code。至少在的Java API没有可能运行在不同的线程池异步工作

Play framework uses the same default thread pool, in which all application code is executed. At least in Java api there is no possibility to run asynchronous work on different thread pool.

所以,我的问题是,它是否值得异步运行潜在的阻塞I / O操作,考虑到这样的操作使用相同的线程池反正事实。或者,也许这是更好地增加默认的线程池的大小,并与异步API在这种情况下不烦? (这样至少code可读性会高很多)

So, my question is if it's worth to run the potentially blocking I/O operation asynchronously, considering the fact that such an operation uses the same thread pool anyway. Or maybe it's better to increase the default thread pool size, and don't bother with async api in such a case? (this way at least code readability would be much higher)

推荐答案

我建议你建立自己的背景,并使用播放 F.Promise&LT运行阻断/ CPU密集型操作存在; A&GT ; 。一如既往地与线程,最佳的解决方案取决于很多事情像内核数量等。

I would recommend that you set up your own context and run your blocking/cpu-intensive operations there using Plays F.Promise<A>. As always with threads, the optimal solution depends on numerous of things like number of cores etc.

首先设置你的背景下 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
        }
      }
    }
  }
}

然后在你的控制器,利用使用播放承诺上下文的(我使用Java 8):

Then in your controller, make use of your context using Plays Promises (I'm using 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()));
}

这样,你的游戏应用仍然会处理在默认调度执行情况和持续时间短的请求阻塞/ CPU密集型将在运行我的上下文

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.

我做了一个很简单的例子给你展示这一点,看看在 github上

I made a very short example for you demonstrating this, check it out on github.

这篇关于玩框架异步处理和阻塞I / O在Java中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆