当前位置: 首页 > 知识库问答 >
问题:

做Future.sequence怎么知道哪个未来失败?

秦禄
2023-03-14

下面是一个我正在工作的演员的例子:

def receive = {
        case "begin" =>
            val listOfFutures: IndexedSeq[Future[Any]] = workers.map(worker => worker ? Work("test"))
            val future: Future[IndexedSeq[Any]] = Future.sequence(listOfFutures)

            future onComplete {
                case Success(result) => println("Eventual result: "+result)
                case Failure(ex) =>  println("Failure: "+ex.getMessage)
            }
        case msg => println("A message received: "+msg)
    }

当对其中一个工作线程的 ask 失败时(在超时的情况下),序列 future 在失败的情况下完成。但是,我想知道哪些工人失败了。有没有一种更优雅的方式,而不是简单地一个接一个地映射listOfFutures而不使用Future.sequence?

共有2个答案

胡飞鹏
2023-03-14

多亏了@O__我想出了另一种可能更适合某些情况的解决方案。

case class WorkerDone(name: String)
case class WorkerFailed(name: String)

import ExecutionContext.Implicits.global

val f = (0 to 10).map {
    i => Future {i/i; WorkerDone(s"worker$i")}.recover{
        case ex => WorkerFailed(s"worker$i")
    }
}
val futureSeq = Future.sequence(f)

futureSeq onComplete {
        case Success(list) => list.collect {case result:WorkerFailed => result}.foreach {failed => println("Failed: "+failed.name)}
        case Failure(ex) => println("Exception: "+ex.getMessage)
    }

// just to make sure program doesn't end before onComplete is called.
Thread.sleep(2000L)

我不确定我的例子是否是一个好的实践,但我的目标是知道哪些工人确实失败了,不管他们是如何失败的。

习海
2023-03-14

您可以使用 future 的 recover 方法来映射或包装基础异常:

import scala.concurrent.{Future, ExecutionContext}

case class WorkerFailed(name: String, cause: Throwable) 
  extends Exception(s"$name - ${cause.getMessage}", cause)

def mark[A](name: String, f: Future[A]): Future[A] = f.recover {
  case ex => throw WorkerFailed(name, ex)
}

import ExecutionContext.Implicits.global

val f = (0 to 10).map(i => mark(s"i = $i", Future { i / i }))
val g = Future.sequence(f)

g.value  // WorkerFailed: i = 0 - / by zero
 类似资料:
  • 问题内容: 在我的Jenkins管道中,如果管道发生故障,我通常使用声明性功能向我发送电子邮件。 该函数的简单语法如下: 在上面的电子邮件中,我还想提到管道的哪个阶段(假设管道有5到6个阶段)失败。我怎样才能做到这一点?任何帮助深表感谢。 对上述要求的扩展将是向用户提供实际的错误日志(发生故障的阶段),作为故障通知电子邮件的一部分。 想法是,当用户从jenkins收到故障通知时,他应该知道管道的哪

  • 问题内容: 我想知道pom.xml中描述的哪个依赖性在目标目录中带来了传递性依赖性。 更准确地说,我的WEB-INF / lib目录中有一个库“ poi-2.5.1-final-20040804.jar”,我想知道pom.xml中的哪个依赖项会带来这种情况。 问题答案: 要添加到@David Crow,下面是Maven站点中的dependency:tree示例: 可能输出

  • 问题内容: 我从java2s.com下载了servlet-api.jar的副本。我怎么知道它是什么版本?该网站上没有参考。 编辑 啊。道歉。当我双击得到的jar中的MANIFEST.MF文件时,我应该已经列出了写字板输出的内容: 如您所见,它没有告诉我版本,因此是问题所在。 问题答案: 您可以从META-INF中获取它,也可以使用Win rar或类似的归档工具来探索jar文件的内容。 我个人更喜欢

  • 我想使它从“游戏26”类到“游戏39”类,如果用户经历了从“游戏17”类到“游戏18”类。但如果用户没有通过,要使从“Game26”类到“Game30”类。

  • 我得到了关于在上一个异步操作结束之前在上下文上启动第二个异步操作的错误,但我没有看到它发生在哪里。这是我正在使用的代码。每个异步调用都使用await,那么我做错了什么? 这是Web API 2调用上的一种方法。 当它到达最后一行时,就是抛出异常的地方。 异常消息: 在上一个异步操作完成之前,在此上下文上启动了第二个操作。使用“await”确保在该上下文上调用另一个方法之前已完成任何异步操作。任何实

  • 服务器推送的工作原理是在响应请求后立即发送js、css、图像等,而不是等待客户端接收html、解析它并请求资源,从而节省往返。但是,将js、css、图像、字体等推送给,而这些相同的文件在一分钟前获取时已经被客户端下载,这完全是对带宽的浪费,因为客户端已经拥有这些文件。 为每个请求保留状态服务器端似乎很昂贵,而且不可能这样做,因为HTTP是无状态的。大概,客户端会在后续访问中重新请求html,以查看