在失败的情况下也如何使用多个期货

时间:2019-02-16 12:33:59

标签: scala akka future

我有一个演员,其中有两个Messages首先负责在mongoDB中插入数据,第二个Actor负责在elasticsearch,InserInMongo和InserInES中插入数据 会出现mongodb插入操作失败或ES插入操作由于某些异常而失败的情况,而我正在做这样的事情

try {
        val mongoFuture: Future[Boolean] = ask(artGroupPersistenceActor, PersistArtGroupInMongo(artGroup)).mapTo[Boolean]
        val esFuture: Future[Boolean] = ask(artGroupPersistenceActor, PersistArtGroupInES(artGroup)).mapTo[Boolean]
        val resultMongo = Await.result(mongoFuture, timeout.duration)
        log.debug("store: Record Inserted inserted in mongoDB  {}", resultMongo)
        val resultES = Await.result(esFuture, timeout.duration)
        log.debug("store: Record Inserted in ES  {}", resultES)
}
catch {
        case e: Exception =>
          log.error("store:While inserting an artgroup Exception in artGroupPersistenceActor  actor", e)
          throw e
      }

在这里我想如果mongoFuture失败,那么我会捕获到它的异常,并且应该继续使用esFuture

或者如果两个将来都失败了,我会遇到两个例外情况,如何归档这种情况?

4 个答案:

答案 0 :(得分:0)

您可以尝试这样。

    for {
        x <- Future.successful {
            try {
                code here...
            } catch {
                case _: Exception => 
                    println("Error Inserting In Mongo ")
                    false
            }
        }
        y <- Future.successful {
            try {
                code here...
                    // throw new IllegalStateException("Exception thrown")
            } catch {
                case _: IllegalStateException => 
                    println("Error Inserting In ES ")
                    false
            }
        }

    } yield(x, y)

现在,您可以在执行此过程中进行操作,以防发生错误。祝您好运。

答案 1 :(得分:0)

您可以使用recover,它将处理原始Future包含的所有匹配的throwable:

    val mongoFuture = ask(artGroupPersistenceActor, PersistArtGroupInMongo(artGroup))
        .mapTo[Boolean]
        .recover {
          case e =>
            println("error in mongo: " + e)
            false
        }

      val esFuture = ask(artGroupPersistenceActor, PersistArtGroupInES(artGroup))
        .mapTo[Boolean]
        .recover {
          case e =>
            println("error in ES: " + e)
            false
        }

      val f = Future.sequence(List(mongoFuture, esFuture))
      val result: Seq[Boolean] = Await.result(f, Duration.Inf)

      println(result)

答案 2 :(得分:0)

如果您只想记录例外,只需对每个例外进行记录:

mongoFuture.failed.foreach {ex => logger.error("Mongo error", ex)}

答案 3 :(得分:0)

最好使用maprecover代替Await.result

import akka.pattern.ask
import scala.concurrent.duration._

implicit val timeout : akka.util.Timeout = 20.seconds

for{
  mongoResult <- (artGroupPersistenceActor ? PersistArtGroupInMongo(artGroup)).mapTo[Boolean]
  .recover{ 
    case _ => 
      log.error("mongodb error") 
      false
    }
  elasticResult <- (artGroupPersistenceActor ? PersistArtGroupInES(artGroup)).mapTo[Boolean]
  .recover{ 
    case _ => 
      log.error("elastic error") 
      false
    }
} yield {
  (mongoResult, elasticResult)
}