ScalaのFutureで(あるいはPlay?)で処理がブロックされてしまう現象があった。
環境
- Scala 2.10.1
- Play 2.1.3
- (Playのモデルクラスを使っているだけで、scalaコマンドから起動されるバッチ処理)
簡略化するとこんなコード(実際はもっと分割されてるし、whileじゃなくてtailrecだけど)。
import scala.concurrent.Await import scala.concurrent.duration._ import play.api.libs.concurrent.Execution.Implicits._ for { photo <- listOfPhotos } yield { // downloadはサードパーティライブラリのメソッドで // Future[java.io.File]を返す val fut = photo.download map { file => Logger.debug("start!") //ここまでは実行される。 // SomeApi.postFileの挙動は、responseが返るまでブロックする。 // しかし、↓が実行されない SomeApi.postFile(file) map { jobId => var complete = false var result = None while (!complete) { Thread.sleep(5000) val job = SomeApi.getJob(jobId) if (job.isComplete()) { complete = true result = job.getResult() // resultに対して処理 } } } } try { Await.result(fut, 120 seconds) } catch { case e: Exception => Logger.error(e.getMessage()) } }