gpt4 book ai didi

akka - 从父 actor 到子 actor 的消息上的死信,当父 actor 在发送消息后停止时

转载 作者:行者123 更新时间:2023-12-05 01:28:14 24 4
gpt4 key购买 nike

考虑以下代码示例(版本 1)。此处父 actor (ActorA) 向子 actor (ActorB) 发送消息,然后停止自身。由于父 actor 的自停止,在高负载下,子 actor 甚至在从邮箱中提取消息之前就已经死了,因此消息变成了“死信”(请参见下面的示例输出 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)。通过引入从子 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

现在我的问题是,有没有其他方法可以达到同样的目的?我的意思是摆脱死信。

最佳答案

当父级停止时,其所有子级都将停止。那是造成死信的原因。确保没有死信的唯一方法是确保在 child 收到消息之前 parent 还活着。除了 ack 消息,我想不出任何其他方式。

关于akka - 从父 actor 到子 actor 的消息上的死信,当父 actor 在发送消息后停止时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25739476/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com