我编写了一个应用程序 (Scala) Play,当我在本地机器上运行它时,它的工作方式完全符合我的预期。我正在研究的方法(可能还有其他人有这个问题,我没有仔细检查过)是一种由 POST 请求触发的方法。它返回一个 Async 对象,因为该方法完成的评估返回一个 Future。
但是当我部署它时,这种方法的行为完全不同。我整天都在追这个问题,但我已经到了无法解释发生了什么的地步。
该方法看起来像这样:
def add = Action(parse.json) { request =>
Async {
val req = request.body.asOpt[TaskRequest] map { r =>
val job = createJob(r)
submitJob(job, r)
job map { ij =>
allowOrigin(Created(ij).withHeaders("Location" -> routes.Jobs.read(ij._id.stringify).url));
}
}
req.get
}
}
总的来说,这很简单。该createJob
方法返回一个Future[Job]
. 该submitJob
调用是一种“触发并忘记”调用,用于触发一些背景内容(我对等待不感兴趣)。然后我处理job
结果以在创建Result
对象时生成一个对象。job
正如我上面描述的那样,所有这些都在我的本地机器上工作。但是当我部署它时,发生了一些非常奇怪的事情。该submitJob
调用触发了长时间运行的计算。正如我所说,我对等待它不感兴趣,这就是为什么我什至不使用Future
它在任何地方返回的原因。
但奇怪的是……在我的开发机器上,我的 POST 请求(直接调用 add)的响应在创建作业后立即返回。submitJob
但是在部署机器上,我只有在任务完成后才能得到响应!换句话说,我req
认为Future
它似乎与该submitJob
调用完全无关(它当然不取决于其结果),但在部署环境中,Async
块在完成之前不会返回submitJob
(即使req
已完成几乎立即)。
这到底是怎么回事?我已经在println
整个代码中添加了语句。它肯定会req.get
几乎立即通过那个电话。但是整体(HTTP)响应肯定会等到submitJob
完成。Async
不知何故知道submitJob
电话?如果是这样,为什么它在两台不同的机器上表现不同?
有任何想法吗?