8

在 Scala 中,当另一个(远程)actor 终止时,可以通过设置 trapExit 标志并以第二个 actor 作为参数调用 link() 方法来通知一个 actor。在这种情况下,当远程参与者通过调用 exit() 结束其工作时,第一个参与者通过接收退出消息得到通知。

但是当远程参与者以不那么优雅的方式终止时会发生什么(例如,它正在运行的 VM 崩溃)?换句话说,本地参与者如何发现远程参与者不再可用?当然,我希望(如果可能的话)可以通过类似于退出消息的消息通知本地参与者,但这似乎不可行。我错过了什么吗?我应该不断地轮询远程参与者的状态(在这种情况下,我不知道哪种方法是最好的方法)还是有更聪明的解决方案?

4

2 回答 2

4

Scala 中的 Actors一书提到(未经个人测试):

捕获终止通知。

在某些情况下,接收终止通知作为监控参与者邮箱中的消息很有用。
例如,监控参与者可能想要重新引发某个链接参与者未处理的异常。
或者,监控参与者可能想要对正常终止做出反应,这在默认情况下是不可能的。

Boolean trapExit参与者可以配置为使用标志在其邮箱中接收所有终止通知作为正常消息。在以下示例中,actorb将自身链接到 actor a

val a = actor { ... }
val b = actor {
self.trapExit = true
link(a)
...
}

请注意,在 actorb调用链接之前,它会将其trapExit成员设置为true;
这意味着每当链接的参与者终止(正常或异常)时,它都会收到 Exit 类型的消息
因此,b每当actor终止时都会通知actor a(假设actor在调用链接a之前没有终止)。b

那么“当远程参与者以不那么优雅的方式终止时会发生什么”?即使在异常终止的情况下,
它也应该收到一条消息。Exit

val b = actor {
  self.trapExit = true
  link(a)
  a ! 'start
  react {
    case Exit(from, reason) if from == a =>
    println("Actor 'a' terminated because of " + reason)
  }
}
于 2010-11-29T14:18:43.233 回答
4

但是当远程参与者以不那么优雅的方式终止时会发生什么(例如,它正在运行的虚拟机崩溃)

Actor 代理保持活动状态,接受消息(并丢失它们),并等待您使用远程 Actor 重新启动 JVM。监视 JVM 崩溃(以及发生在基础设施级别的其他故障)远远超出了 Scala 的职责。不错的选择可能是通过 JMX 进行监控。

换句话说,本地参与者如何发现远程参与者不再可用?

您可以定义一个超时间隔(比如 5000 毫秒)。如果远程actor在此时间间隔内没有回复,则表明远程actor发生了意外情况,您可以询问它的状态或将其视为已死亡。

我应该不断地轮询远程参与者的状态(在这种情况下,我不知道哪种方法是最好的方法)还是有更聪明的解决方案?

您可以在一组参与者前面放置一种轮询负载均衡器/调度程序,它将仅使用那些活着并准备好处理消息的参与者(这在远程参与者可能突然出现/消失的情况下是有意义的代理)-> Scala 演员可以同时处理多条消息吗?

于 2010-11-29T15:41:58.613 回答