考虑下面的代码示例(版本1)。这里父actor(ActorA)向子actor(ActorB)发送消息然后停止self。由于父母演员的自我停止,在高负荷下,儿童演员甚至在从邮箱挑选消息之前就死了,因此消息变成了“死信”。 (参见下面的示例输出1)。
出于某种原因,我无法修改应用程序设计以删除父actor的自动停止。
版本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
现在我的问题是,还有其他方法可以达到同样的目的吗?我的意思是摆脱死信。
答案 0 :(得分:1)
当父母停止时,其所有孩子都将被停止。这导致死信。确保没有死信的唯一方法是确保父母活着,直到孩子收到消息。除了ack
消息之外,我无法想到任何其他方式。