Play Framework:以阻塞方式调用异步未来时,无限制地创建新线程

时间:2014-07-03 15:41:24

标签: multithreading scala asynchronous playframework-2.0

我有以下代码:

 import scala.concurrent.ExecutionContext.Implicits.global

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

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

基本上WS.url将返回Future [ws.Response],所以在上面的代码中我想监视以阻塞方式调用此服务的行为。在我的动作中,我正在等待结果然后显示响应体。我试图用2000个并发用户进行20秒斜坡。问题是上面的代码创建了大量的新线程,播放实例关闭了错误"java.lang.OutOfMemoryError : unable to create new native Thread"。这完全不是预期的行为。我正在使用默认执行上下文,因此该池只有核心+ 1个线程。为什么上面创建了大量的线程?

2 个答案:

答案 0 :(得分:2)

Await.resultscala.concurrent.blocking包裹等待结果的阻塞等,通知ExecutionContext它正在阻止。默认的ExecutionContext由fork-join池支持,然后它会快速饿死,因为它只有核心数量的线程,而它会产生一个新的线程来保持非线程的可用线程数阻止操作相同。

答案 1 :(得分:0)

请改为:

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)
  ))
}