【问题标题】:Fail an actor if a Future call fails如果 Future 调用失败,则让 actor 失败
【发布时间】:2017-02-09 00:54:56
【问题描述】:

我将在未来的通话中执行某些操作。我将在成功完成时将结果返回给发送者,或者如果未来的调用失败,则让参与者失败。这将由实现具有监督策略的 RoundRobinPool 的父级处理。

这里是代码sn-p。

private def getData(sender: ActorRef): Unit = {

    dao.getData().mapTo[List[Data]].map(result => sender ! result)
      .onFailure {
        case e: NullPointerExcetpion => {
          println("+++++++ Throwing exception")
      // throwning the exception from here doesn't cause the supervisor to restart this actor
          throw t
        }
      }

      // throwing the exception from here makes the supervisor strategy to take action
      throw new NullPointerExcetpion

  }

如果future返回异常,我们如何让actor失败?

干杯,

乌萨夫

【问题讨论】:

  • 你所说的“失败的演员”是什么意思?
  • 将其传播回用户并杀死参与者。会导致主管重新启动actor的行为。由于 SupervisorStrategy.Restart 用于在出现空指针异常的情况下在主管中。
  • 更重要的是,为什么当我从 Future 函数之外显式抛出错误时它会起作用?

标签: scala akka


【解决方案1】:

问题在于onFailure 回调是从任意线程抛出的,而不是actor 正在运行的线程。您可以做的是将结果传递给自己,然后抛出:

case class MyFailure(e: Throwable)

def receive: {
  case MyFailure(e) => throw e
}

private def getData(sender: ActorRef): Unit = {
  dao
   .getData()
   .mapTo[List[Data]]
   .recover {
     case e => MyFailure(e)
   }
   .pipeTo(self)
}

或者正如@jrudolph 建议的那样:

def receive: {
  case Status.Failure(e) => throw e
}

private def getData(sender: ActorRef): Unit = {
  dao
   .getData()
   .mapTo[List[Data]]
   .pipeTo(self)
}

【讨论】:

  • 或者即使没有recover,也可以接收pipeTo提供的Status.Failure(ex)消息。
  • 我仍然可以在未来的实际通话中保留地图,对吧?
  • @user520209 当然,您只需要在接收方法中添加一个案例,该案例接受如果未引发异常则返回的结果类型。
  • 我的意思是我是否仍然可以直接将结果发送给 map pf 中的发送者,以防将来调用成功,就像问题中一样,而不必将结果传递给 self。
  • @user520209 您可以添加一个将消息传递给发件人的映射,但无论如何仍会将结果发送给您自己。将它传递给自己然后将其传递给发件人会更干净。如果您愿意,可以使用 become 而不是将其添加到当前接收中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 2016-05-09
  • 2018-08-20
  • 2016-05-27
相关资源
最近更新 更多