如何在其中一个路由器actor抛出异常时处理失败

时间:2017-01-18 18:47:34

标签: scala akka

假设我有一个电子邮件发件人,负责发送电子邮件。 我想限制为发送电子邮件而创建的演员数量,所以我创建了一个路由器。

class EmailSender extends Actor {

    val router = context.actorOf(RoundRobinRouter(4).props(EmailSender.props))

    def recieve = {
        case SendEmail(emailTo: String, ..) =>
            router ! SendEmailMessage(emailTo,.. )
        case ...
    }
}

我想在这里理解两件事:

  1. 如果某个路由器演员发送的电子邮件失败,EmailSender将如何收到通知,我是否会收到失败的确切电子邮件?

2 个答案:

答案 0 :(得分:1)

如果电子邮件发送在Routee演员中失败,则默认监督策略是重新启动演员。

因此,您应该能够挂钩preRestart方法并查看导致EmailSender失败的消息。

class EmailSender extends Actor {

    def recieve = {
        case SendEmail(emailTo: String, ..) =>
            router ! SendEmailMessage(emailTo,.. )
        case ...
    }
    override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
       // log the failed message. Or send it back to failedMsg processer
       if (message.isDefined) {
         failedEmailsProcessor ! message.get
       }
    }

 }

注意:我的监督策略是AllForOneStrategy,然后将为所有子actor调用preRestart。所以最好在这里使用OneForOneStrategy,这样只为失败的actor调用preRestart。

答案 1 :(得分:0)

在包含路由器的类中,您将电子邮件放入待处理电子邮件列表中。

当电子邮件成功发送到EmailSender时,它会发回一条消息说成功,如果从待处理列表或失败消息中,路由器类将删除它,路由器可以再试一次,具体取决于您的业务逻辑