我正在尝试构建基于代理的模型,其中部分模型涉及代理广播决策。首先,我会使用跟踪父对象准确地初始化四个参与者,然后让他们每个人以特定顺序“宣告”他们的决定。
我希望每个兄弟姐妹每次声明其决定时都会更新其参数,但是当我运行下面显示的代码时,我会得到有关遇到死信的日志。如何确保所有参与者按顺序运行,从兄弟姐妹那里接收所有声明,并且在他们收到一条声明自己的消息之前不终止?
主要方法:
import Member._
val system: ActorSystem = ActorSystem("Abilene0")
try {
val groupMembers = Set("father", "mother", "wife", "husband")
val group: ActorRef = system.actorOf(Group.props(groupMembers), "group")
val father = system.actorOf(Member.props(group, generate(groupMembers)), "father")
val mother = system.actorOf(Member.props(group, generate(groupMembers)), "mother")
val wife = system.actorOf(Member.props(group, generate(groupMembers)), "wife")
val husband = system.actorOf(Member.props(group, generate(groupMembers)), "husband")
father ! Declare
wife ! Declare
husband ! Declare
mother ! Declare
} finally {
system.terminate()
}
答案 0 :(得分:1)
通过查看您的代码,很明显参与者消息将传递到deadletters
。在您的代码中,您正在try-catch-finally语句的system.terminate()
块中调用finally
,这意味着actor系统终止将在try块之后立即发生,这将立即停止所有演员。但是,您应该知道 Actor使用异步消息进行通信。这意味着,即使在您的try-block代码完成之后,在actor中仍可能执行各种后台任务,直到所有actor停止为止。
让我为您创建一个方案:
class Handler extends Actor with ActorLogging{
override def receive: Receive = {
case "START" =>
println("Test Started.")
}
}
class Tester(handler: ActorRef) extends Actor with ActorLogging{
override def receive: Receive = {
case "TEST" =>
println("Test started.")
// Here, when handler actor stops when system.terminate() occur, "START" message
// will be no longer delivered to actor handler instead delivered to deadletters.
1 to 1000 foreach ( _ => {
handler ! "START"
})
}
}
val system: ActorSystem = ActorSystem("test")
val handler = system.actorOf(Props(new Handler), "handler")
val tester = system.actorOf(Props(new Tester(handler)), "tester")
try {
tester ! "TEST"
} finally {
system.terminate()
}
在上述代码中,当调用system.terminate()
时,handler
actor停止,然后tester
actor停止。但是,在tester
actor停止之前,仍然可能有"START"
消息被发送到handler
actor。但是,handler
actor已经停止,此"START"
消息将不再传递给handler
,因此也传递给deadletters
。
因此,在您的代码中,执行system.terminate()
后,所有参与者-group
,father
,mother
,wife
和husband
会立即停止,因此发送到这些actor邮箱的所有其他消息都会传递给合成actor deadletters
。
我如何确保所有参与者按顺序运行,接收所有声明 从兄弟姐妹那里,直到他们收到一条消息到 声明自己?
为此,您可以将PoisonPill
消息显式传递给每个actor,只有在处理了其邮箱中的所有消息之后,才会停止actor。