考虑以下代码示例(版本1)。在这里,父级演员(ActorA)向子演员(ActorB)发送消息,然后停止自己。由于父级演员自我停止,当负载高时,子演员甚至在从邮箱中获取邮件之前就死亡,因此消息成为“死信”(请参见下面的示例输出1)。
出于某种原因,我无法修改应用程序设计以删除父级演员的自我停止。
版本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)。通过从子actor到父actor的消息确认,然后在收到这个确认后自行停止父actor,可以摆脱死信问题(请参见样本输出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
现在我的问题是,是否有其他方法来实现相同的目的?我的意思是摆脱死信。