在做Future.sequence时如何知道哪个Future失败了?

Öme*_*Gül 4 scala akka

以下是我正在处理的演员接收部分的示例:

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)
    }
Run Code Online (Sandbox Code Playgroud)

当其中一个工作者询问失败时(如果发生超时),序列将来会以失败告终.但是我想知道哪些工人失败了.有没有更优雅的方式,而不是简单地逐个映射listOfFutures而不使用Future.sequence

0__*_*0__ 7

您可以使用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
Run Code Online (Sandbox Code Playgroud)