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

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>