【问题标题】:Either wait for a function to finish or timeout after 5 seconds in Akka在 Akka 中等待函数完成或 5 秒后超时
【发布时间】:2015-04-21 18:45:54
【问题描述】:

我正在尝试等待函数在 5 秒后完成或超时,但无论我做什么,我都无法阻止以下异常。有趣的是它被父actor捕获:

java.util.concurrent.TimeoutException: Futures timed out after [5 seconds]

我尝试过的解决方案之一(来自this 问题):

val f = Future { dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec() }
val result: Try[InputStream] = Await.ready(f, 5.seconds).value.get

val resultEither = result match {
  case Success(t) => log.info("right")
  case Failure(e) => log.info("left")
}

【问题讨论】:

  • 你看到所有其他选项了吗? Await 是阻塞和邪恶的... semberal.github.io/scala-future-timeout-patterns.html
  • @AndreyTyukin 谢谢你的文章。我使用询问模式解决了它。
  • 人们通常会用这种“答案”做什么?关闭问题,以便没有人可以利用 semberal 的知识?
  • @AndreyTyukin 要么保持原样,要么添加一个简单的询问模式用法作为答案,说明它如何通过链接到 semberal 的文章获取详细信息来解决问题。这是我的代码的简化版本;如果你愿意,你可以使用它:pastebin.com/LXPpgWeS
  • @AndreyTyukin 或者我们可以创建一个关于它的 wiki 类型的帖子。

标签: scala akka


【解决方案1】:

确实可以使用 akka ask 模式来实现这一点。但是有一个不同的解决方案可以在没有 akka 的情况下使用。

将您的阻塞 Await 代码包装到另一个 Future 并注册 onComplete 函数

import concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
import scala.util.{Failure, Success, Try}

val sleepTimeout = 1*1000

val f = Future( Thread.sleep(sleepTimeout); Try(10))
val timeoutFuture = Future(Await.result(f, 5.seconds))
timeoutFuture.onComplete {
  case Success(Success(t))  => println(t)
  case Success(Failure(ex))  => println("error on Try" + ex.getMessage)
  case Failure(e) => println("timeout " + e.getMessage)
}

解释匹配案例

  • Success(Success(t)) 首先SuccesstimeoutFuture,表示它没有超时。第二个SuccessTry - 表示没有抛出异常。
  • Success(Failure(ex)) 与第一个相同,但Try 内有异常
  • Failure(e) 这是处理超时的地方。

【讨论】:

猜你喜欢
  • 2020-05-19
  • 1970-01-01
  • 2020-08-15
  • 2014-05-10
  • 1970-01-01
  • 2017-05-08
  • 1970-01-01
  • 2017-10-30
  • 1970-01-01
相关资源
最近更新 更多