Как использовать несколько фьючерсов в случае неудачи - PullRequest
0 голосов
/ 16 февраля 2019

У меня есть актер с двумя сообщениями, первый из которых отвечает за вставку данных в mongoDB, а второй - за вставку данных вasticsearch, 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 голосов
/ 17 февраля 2019

лучше использовать map и recover вместо 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)
}
0 голосов
/ 16 февраля 2019

Вы можете пойти с recover, который будет обрабатывать любые подходящие броски, которые содержит исходное Будущее:

    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)
0 голосов
/ 17 февраля 2019

Если вы просто хотите регистрировать исключения, просто сделайте это с каждым из них:

mongoFuture.failed.foreach {ex => logger.error("Mongo error", ex)}
0 голосов
/ 16 февраля 2019

Вы можете попробовать вот так.

    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)

Теперь вы можете манипулировать, если во время процесса произошла ошибка. Удачи.

...