按路径获取多个akka Actor实例的ActorRef



我正在创建一个相同Actor的实例池
以后在我的应用程序中,我希望能够引用一个演员的特定实例"pool">

val instance1 = context.spawn(ActorA(), "actorA_1")
val instance2 = context.spawn(ActorA(), "actorA_2")
val instance3 = context.spawn(ActorA(), "actorA_3")
etc

这是在应用程序初始化时完成的,目标是允许应用程序的任何参与者在知道其唯一路径…

时引用该实例

。我想实现这样的东西:

val actorRef = getActorByItsUniquePath(path) 
actorRef ! sendMessage(...)

我不知道我是否需要使用经典Actor Api或类型化Api(接待员)和/或如果我需要在HashMap上存储每个Actor实例的唯一路径(路径+ UID)并稍后检索此路径。

我在文档中找不到任何明确的实施方向。

你在正确的道路上。在Classic Actors中,这是通过actor选择和actor路径完成的。注意"唯一路径"可能必须在集群设置中包含该节点。

在typed Actors中,您将使用接待员和ServiceKey作为您的"唯一路径"。

所以,你不需要使用一个API或另一个:你应该使用经典的演员或类型的演员,你喜欢。只需根据您选择的API选择发现方法(ActorPath或接待员)。

但是,我要添加一个警告。一般来说,最好不要这样做。您正在有效地向客户端公开实现细节。并消除一些灵活性/弹性。这在文档中有讨论:https://doc.akka.io/docs/akka/current/actors.html#identifying-actors-via-actor-selection "使用其他actor的ActorRef而不是依赖于ActorSelection总是更好的。异常:"。这并不是说你绝对不应该这样做,因为演员发现api的存在显然是有原因的。只是你应该"更喜欢"。不要依赖于通过唯一路径查找actor,而且你应该有一个很好的理由不使用路由器之类的东西。

编辑回复评论:

您在下面的评论中说您将有具有相同路径的actor实例,但这是不可能的。Actor路径是唯一的*;每个实例都有唯一的路径。似乎您可能认为路径与参与者相关联,但路径是参与者实例。请参阅文档和经典文档中关于命名actor的部分,其中讨论了必须为每个实例提供唯一名称的事实。如果您没有显式地为实例提供唯一的名称,系统将自动生成一个。(例如/user/myactor/1美元/user/myactor/2美元,…)

如果你已经生成了一个uid,只要在你生成它的时候指定它作为实例的名称,你最终会得到一个路径,看起来像:akka://my-actorsystem@mynode:port/user/parentactor/youruid,你将能够使用该路径来查找它。

你的情况真的没有那么不寻常。这是一种非常常见的模式,具有相同参与者的许多实例,每个实例维护状态。这也是我提到使用路由器模式的原因,因为这种设计具有更大的灵活性。事实上,这也是Akka Sharding背后的基本模式。您可能也想把它作为一个选项来研究,特别是在使用集群的情况下。

如果你使用接待员和键入的演员,它基本上是在Receiptionist文档中显示的完全相同的例子。每次创建一个新的actor实例时,您都要用register消息和您的uid密钥向接待员注册它。然后,您只需稍后在查找消息中查找它。这有点复杂,因为接待员不强制惟一性(不像路径),因为你必须知道类型(因此适应响应类型),但这就是接待员的全部内容:作为你发送消息的参与者实现的参与者实例的键值存储。

*技术上,actor路径对于活的actor实例是唯一的。理论上,您可以创建一个actor/user/foo,停止它,然后使用相同的名称创建第二个实例。但是我不想把上面的解释复杂化,因为我不认为细节在这里是重要的。