在Scala中,当另一个(远程)actor终止时,可以通过设置trapExit标志并以第二个actor作为参数调用link()方法来通知actor。在这种情况下,当远程actor通过调用exit()结束其作业时,通过接收Exit消息来通知第一个。
但是当远程actor以不太优雅的方式终止时(例如运行崩溃的VM)会发生什么?换句话说,本地演员如何发现远程演员不再可用?当然我更希望(如果可能的话)可以通过类似于Exit 1的消息通知本地actor,但似乎不可行。我错过了什么吗?我是否应该不断轮询远程参与者的状态(在这种情况下我不知道哪种方式最好)或者是否有更智能的解决方案?
答案 0 :(得分:4)
这本书 Actors in Scala 提及(未亲自测试):
在某些情况下,将终止通知作为监视行为者邮箱中的消息接收是很有用的 例如,监视actor可能想要重新抛出一些未被某个链接actor处理的异常 或者,监视参与者可能希望对正常终止做出反应,这在默认情况下是不可能的。
参与者可以使用
Boolean
trapExit
fl ag配置为在其邮箱中接收所有终止通知作为普通邮件。在以下示例中,actorb
将自己链接到actora
:
val a = actor { ... }
val b = actor {
self.trapExit = true
link(a)
...
}
请注意,在演员{{1}}调用链接之前,它会将其
b
成员设置为trapExit
;
这意味着每当链接的actor终止(正常或异常)时,它都会收到Exit 类型的消息。
因此,只要actortrue
终止(假设actorb
在a
调用链接之前没有终止),actora
就会被通知。
那么“当远程演员以不太优雅的方式终止时会发生什么”?
即使在异常终止的情况下,它也应该收到b
消息。
Exit
答案 1 :(得分:4)
但是当远程actor以不太优雅的方式终止时(例如运行崩溃的VM)会发生什么呢?
Actor代理保持活动接受消息(并丢失它们),并等待您使用远程actor重新启动JVM。监视JVM崩溃(以及基础架构级别发生的其他故障)远远超出了Scala的职责。可以通过JMX进行监控。
换句话说,本地演员如何发现远程演员不再可用?
您可以定义超时间隔(例如5000毫安)。如果远程演员在此间隔期间没有回复,则表明远程演员发生了意外事件,并且您可能询问其状态或仅将其视为已死。
我是否应该不断轮询远程参与者的状态(在这种情况下我不知道哪种方式最好)或者是否有更智能的解决方案?
您可以在一组演员面前放置一种轮询负载均衡器/调度程序,这些演员只会使用那些活着且准备好处理消息的演员(这对于可能突然出现的远程演员来说是有意义的/在代理后面消失) - > Can Scala actors process multiple messages simultaneously?