0
votes

I have a following code:

 import scala.concurrent.ExecutionContext.Implicits.global

  def index = Action {
      Ok(Await.result(callSync, 10.seconds).body)
  }

  def callSync = {
    WS.url("http://yahoo.jp").get
  }

Basically WS.url will return Future[ws.Response] so in the code above I wanted to monitor the behaviour of this service when invoked in blocking manner. In my action, I am waiting for the result then displaying the response body back. I am attempting this with 2000 concurrent users with 20sec ramp. Problem is that above code creates new threads in massive amount that play instance shuts down the the error "java.lang.OutOfMemoryError : unable to create new native Thread". This is totally not expected behaviour. I am using the default execution context, so this pool will only have core + 1 threads. Why is above creating massive amount of threads?

2
I'm not sure, but if 2000 users trigger your action, won't the callSync be called 2000 times and thus spawning multiple threads? To me this looks like the correct behaviour, how many user access your action should be up to you, not the framework, unless I'm missing something.Ende Neu
I expected some requests to be rejected, since all the existing threads are occupied at some point handling the request in blocking manner. I thought Future{blocking{}} is the only way play will create extra threads as needed.user_1357

2 Answers

2
votes

Await.result wraps the blocking wait for a result with scala.concurrent.blocking which informs the ExecutionContext that it is blocking. The default ExecutionContext is backed by a fork-join pool which would then starve quickly since it only has got as many threads as there is cores and instead it will spawn a new thread to keep the number of available threads for non-blocking operations the same.

0
votes

Do this instead:

import play.api.libs.concurrent.Promise

def index = Action.async {
  Future.firstCompletedOf(List(
    callsync.map(x => Ok(x.body)),
    Promise.timeout(Ok("an error occurred"), 10.seconds)
  ))
}