1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[scala][play2.5.x] timeout処理を行う

Posted at

前提

この記事はplayframework 2.5.x系を使っている。
最新バージョンである、2.8.xでは、実装が大きく異なるので要注意。

環境

  • macOS Mojava 10.14.4
  • Scala 2.11.1
  • playframework 2.5.x

実装

標準ライブラリでできるタイムアウト処理としては、3通りできるっぽい。

1. play.api.libs.concurrent.Timeoutを使う

公式ドキュメントには、この実装方法が記載されているが、どうやっても、play.api.libs.concurrent.Timeoutが見つからない(importできない)ので、諦めた・・・

2. Futures.timeoutを使う

Futures.timeoutを使って、タイムアウト処理を実装します。

基本的に、playのドキュメントに記載している実装を行う


val response: Future[Int] = Future(1)
val timeoutFuture = Futures.timeout("timeout", 1000L, TimeUnit.MILLISECONDS).asScala

Future.firstCompletedOf(Seq(response, timeoutFuture)).map {
  case message: String => { // タイムアウト時の処理 }
  case value: Int => {// 正常時の処理}
}

Futures.timeoutは、Javaのライブラリなので、asScalaメソッドでscalaのコードに変換する必要がある。
firstCompletedOfメソッドは、引数に受け取ったFutureの中で一番初めに処理が終わった物を返すメソッドである。

参考

3. akka.pattern.afterを使う

2で利用したライブラリはJavaのライブラリなので、scalaで書かれているライブラリで実装してみる。
調べてみるとplay.api.libs.conccurent.Promiseでの実装方法が多くヒットする。

しかし以下のように、play.api.libs.conccurent.Promiseのtimeoutメソッドを使おうとすると、play2.5からは、akka.pattern.afterを使うように警告が出る。

Promise.timeout

@deprecated("Use akka.pattern.after(duration, actorSystem.scheduler)(Future(message)) instead", since = "2.5.0")
  def timeout[A](message: => A, duration: scala.concurrent.duration.Duration)(implicit ec: ExecutionContext): Future[A] = {
    timeout(message, duration.toMillis)
  }
}

akka.pattern.afterを使ってタイムアウト処理を実装してみる。

akka.pattern.after

class Test @Inject()(actorSystem: ActorSystem) {
  val delayed = akka.pattern.after(FiniteDuration(500L, TimeUnit.MILLISECONDS), actorSystem.scheduler)(Future.failed(new TimeoutException("timeout")))
  val bucketTypeFuture = Future(1)
  try {
    Future.firstCompletedOf(Seq(delayed, intFuture)).map {
      case number: Int => // 正常時の処理
      case _ => // 正常だが、意図しないレスポンスの場合の処理
    }
  } catch {
    case e: TimeoutException =>
      logger.info(e.getMessage)
      // タイムアウト時の処理
  }
}

基本的に2と同じような実装内容になっている。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?