我已經編寫了一個應用程序(Scala)Play,當我在本地機器上運行它時,它的工作原理與我預期的完全相同。我正在處理的方法(可能有其他問題,我沒有廣泛檢查)是由POST請求觸發的方法。它返回一個Async對象,因爲該方法完成的評估返回一個Future。(Scala)中的異步請求播放「掛起」
但是,當我部署它時,這種方法的行爲非常不同。我一整天都在追逐這件事,但我已經到了無法解釋發生什麼事情的地步。
的方法看起來是這樣的:
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
電話?如果是這樣,爲什麼它在兩臺不同的機器上表現不同?
任何想法?
部署機器是否在您的控制之下?你能從兩臺機器獲得堆棧轉儲並進行比較嗎? – huynhjl
我不確定我明白你的意思。這裏沒有堆棧跟蹤,因爲沒有異常。如果我想嘗試轉儲堆棧(沒有例外),我不知道我該怎麼做,或者在哪裏? –
抱歉,我的意思是一個線程轉儲。如果你下載了一個像http://visualvm.java.net/這樣的工具,或者通過向Windows中的進程或CTRL-BREAK發送SIGQUIT來創建線程轉儲,那麼你可以看到JVM中所有線程的堆棧調用。找出根本原因很有幫助。 – huynhjl