2017-01-18 13 views
0

私は電子メールの送信を担当する電子メール送信者を持っているとします。 電子メールを送信するために作成されたアクターの数を制限したいので、私はルータを作成しました。ルータの俳優の1人が例外をスローしたときの失敗の処理方法

class EmailSender extends Actor { 

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

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

私はここで2つのことを理解したい:

  1. 送信する電子メールメッセージは、電子メールの送信が通知されますと、私は失敗した正確な電子メールを取得する方法を、ルータの俳優の一人で失敗した場合は?
+0

私は1つのことを忘れてしまったと思います:) "ここで2つのことを理解したい" – pedrorijo91

答えて

1

電子メールの送信がルートアクター内で失敗した場合、デフォルトの監督戦略はアクターを再起動することです。

したがって、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 
     } 
    } 

} 

注: I監督の戦略が、その後preRestartは、すべての子役のために呼び出されますAllForOneStrategyです。したがって、ここでOneForOneStrategyを持つ方が良いです。そのため、preRestartは失敗したアクタに対してのみ呼び出されます。

+1

'.isDefined' +' message.get'の代わりにメッセージをマップすることをお勧めします。 – pedrorijo91

+0

私はそれに気づきました例外がスローされ、ログにはルータのすべてのアクターが再起動されているのがわかりました。 –

0

ルーターを含むクラスでは、電子メールをリストの保留電子メールに入れます。

電子メールがEmailSenderに正常に送信されると、成功を知らせるメッセージが返され、保留中のリストまたは失敗メッセージからルータのクラスが削除し、ビジネスに応じてもう一度試すことができます論理。

+0

私が永続性を使用していない場合、サーバーを再起動すると、それらのメッセージは失われます。物事の側面も考慮する必要があります。 –

+0

このためにデータベースを使用できます。 返信する再試行/失敗メッセージに使用できるデッドレター機能がいくつかあります。 –

関連する問題