/ 親の俳優から子の俳優へのメッセージのデッドレター、メッセージの送信後に親が停止したとき - アクター、俳優

親の俳優から俳優へのメッセージのデッドレター、メッセージの送信後に親が停止したとき - アクター、俳優

以下のコード例(バージョン1)を検討してください。 ここでは、親アクタ(ActorA)が子アクタ(ActorB)にメッセージを送信し、次に自己を停止します。親俳優の自己停止により、高負荷では子供の俳優はメールボックスからメッセージを選ぶ前にも死ぬので、メッセージは「デッドレター」になります(下記のサンプルアウトプット1を参照)。

何らかの理由で、親の俳優の自己停止を取り除くためにアプリケーション設計を変更することはできません。

バージョン1

import akka.actor.Actor
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Stop
import akka.actor.Props
import akka.actor.ActorSystem

object AkkaTest extends App {

val system = ActorSystem("AkkaTest")

for (i <- 1 to 5) {
system.actorOf(Props[ActorA]) ! i
}

}

class ActorA extends Actor {

def receive = {
case i: Int => {
context.actorOf(Props[ActorB]) ! i
context.stop(self)
}
}

override def postStop = println("ActorA - stopped")

}

class ActorB extends Actor {

def receive = {
case i: Int => {
println("ActorB - processing msg - " + i)
}
}

override def postStop = println("ActorB - stopped")

}

サンプル出力1

ActorB - processing msg - 2
ActorB - processing msg - 1
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - processing msg - 3
ActorB - stopped
ActorA - stopped
ActorA - stopped
[INFO] [09/09/2014 08:26:56.101] [AkkaTest-akka.actor.default-dispatcher-6] [akka://AkkaTest/user/$e/$a] Message [java.lang.Integer] from Actor[akka://AkkaTest/user/$e#-289783076] to Actor[akka://AkkaTest/user/$e/$a#-86921027] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings "akka.log-dead-letters" and "akka.log-dead-letters-during-shutdown".
[INFO] [09/09/2014 08:26:56.101] [AkkaTest-akka.actor.default-dispatcher-3] [akka://AkkaTest/user/$d/$a] Message [java.lang.Integer] from Actor[akka://AkkaTest/user/$d#-1255514179] to Actor[akka://AkkaTest/user/$d/$a#402128903] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings "akka.log-dead-letters" and "akka.log-dead-letters-during-shutdown".
ActorA - stopped
ActorA - stopped
ActorA - stopped

次に、コードの変更点(バージョン2)を検討します。 子アクターから親アクターへのメッセージ肯定応答を導入し、このアクノリッジメントの受信時に親アクターの自己停止により、死んだ文字を取り除く(サンプル出力2を参照)。

バージョン2

import akka.actor.Actor
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Stop
import akka.actor.Props
import akka.actor.ActorSystem

object AkkaTest extends App {

val system = ActorSystem("AkkaTest")

for (i <- 1 to 5) {
system.actorOf(Props[ActorA]) ! i
}

}

class ActorA extends Actor {

def receive = {
case i: Int => context.actorOf(Props[ActorB]) ! i
case m: MsgAck => context.stop(self)
}

override def postStop = println("ActorA - stopped")

}

class ActorB extends Actor {

def receive = {
case i: Int => {
sender ! MsgAck()
println("ActorB - processing msg - " + i)
}
}

override def postStop = println("ActorB - stopped")

}

case class MsgAck()

サンプル出力2

ActorB - processing msg - 4
ActorB - processing msg - 2
ActorB - processing msg - 5
ActorB - processing msg - 3
ActorB - processing msg - 1
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorA - stopped
ActorA - stopped
ActorA - stopped
ActorA - stopped
ActorA - stopped

今私の質問は、同じを達成するための他の方法はありますか?私は死んだ手紙を取り除くことを意味する。

回答:

回答№1は1

親が停止すると、その子はすべて停止する。それは死んだ手紙を引き起こしている。死んだ手紙がないことを確認する唯一の方法は、子供がメッセージを受け取るまで親が生きていることを確認することです。私は他の方法を考えることはできません ack メッセージ。