我在akka.net中使用远程演员,在长期保持不变的Windows服务中。我使用ActorSelection为远程actor获取IActorRef,并且我在服务中将IActorRef保持活动一段时间。 IActorRef指向在另一个Windows服务中运行的actor系统。 我知道重启远程actor不会使远程actor ref失效。但是,可以想象远程Windows服务可能会在某个时刻重新启动,并且调用Windows服务中的IActorRef将变为无效。
处理此问题的最佳做法是什么? 一个天真的方法是每次我想要调用远程actor时使用ActorSelection来获取新的IActorRef。这显然效率低下。
另一种方法可能是简单地将我在IActorRef上进行的每个调用包装在某种错误处理信封中,该信封捕获异常并使用actorselection和retries获取新的IActorRef?或者信封可能在每次实际调用之前进行测试调用,以查看远程actor是否还活着,如果没有获得新的actor参考。
有更好的方法吗?
答案 0 :(得分:1)
检测死亡演员的默认选项是Watch
他们(参见documentation)。当一个演员观看另一个演员时,一旦观看演员死亡或无法接触,它将收到Terminated
消息。
答案 1 :(得分:0)
观察已终止的消息将警告系统远程演员已经死亡,但是存在如何确切地响应已终止的远程演员的问题。假设一个actor通过它的构造函数获得一个IActorRef到一个远程actor,当它再次变为活动时,actor如何获得一个新的IActorRef到远程actor。一种方法是让actor失败并委托给父actor,然后通过actor选择获得一个新的IActorRef给远程actor。然而,问题在于远程actor的原始actor选择可能发生在组合根中的非actor参数中,其中通常会发生依赖注入。我想你可以通过传递一个actor选择工厂委托绕过它,可以用来重建远程IActorRef。我想出的另一种方法是创建一个实现IActorRef的包装类,名为FaultTolerantActorRef。
此类获取构造函数中远程(或本地)actor的路径,并定期执行actor选择以获取远程actor的刷新IActorRef。这种方式如果由于某种原因远程actor死亡,则FaultTolerantActorRef上的调用将在远程actor死亡时以死信结束。但是,当远程actor最终再次上线时,对FaultTolerantActorRef的调用最终将到达新复活的远程actor,而不必对调用的本地actor进行任何明确的操作。
有一个Invalidate方法,它会强制FaultTolerantActorRef在下次调用时进行新的actor选择。这可以由演员响应来自远程演员的终止消息而调用。即使不调用Invalidate,也会根据传递给构造函数的刷新间隔进行新的actor选择。
Ljava.lang.Object response...