scala - Akka Siblings 递归 ActorRef 要求

标签 scala design-patterns akka actor service-discovery

请允许我抽象一下我经常遇到的 Actor 问题,以及解决它的常见设计模式。假设我有以下参与者层次结构:

── user
    └── ServiceActor
        ├── TicketManager
        │   ├── WorkerA
        │   ├── WorkerB
        │   └── WorkerC
        └── UserManager
            ├── WorkerA
            ├── WorkerB
            └── WorkerC

第一级之外的层次结构,即票证和用户经理并不重要。我要求 TicketManager 向 UserManager 发送消息,反之亦然。 (请注意,这些只是我使用的示例名称,并不代表任何实际问题)

以下哪项最合适?

选项 1:

TicketManager 构造函数将 UserManager 作为构造函数参数。 UserManager 构造函数将 TicketManager 作为构造函数参数。 但是,两者不能相互递归调用,因此这可能无论如何都是不可能的。

选项 2:

UserManager 根据需要通过 actorSelection 作为 actorSelection("../TicketManager") 等对 TicketManager 进行引用,或者仅在启动时引用一次并保留它。

选项 3:

在任何给定时间点,UserManager/TicketManager 都会向其父级 (ServiceActor) 请求对其其他同级的引用,并在父级持有该引用时使用 actorRef 进行适当回复。

选项 4:

这种情况不应该出现吗?我是否应该考虑 sibling 之间的相互交谈,因为这在某种程度上使设计“复杂化”?是否应该有一个更像树的层次结构?如果是这种情况,什么是可以帮助避免这种情况的常见设计模式?

我希望我已经明确了要求,如果需要,请允许我进一步澄清?

最佳答案

如果依赖关系变得复杂,选项 4 可能是最好的方法,但是对于两个 actor,您可以简单地使用消息来初始化它们:actor 被设计为保持可变状态,因此如果您改变它也没关系。

所以我想说,负责创建 TickerManager 和 ActorManager 的父 Actor 可以执行以下操作

case class InitializeTicketManager(userManager:ActorRef)

case class InitializeUserManager(ticketManager:ActorRef)
val userManager = context.actorOf(...)
val ticketManager = context.actorOf(...)
userManager ! InitializeUserManager(ticketManager)
ticketManager ! InitializeTicketManager(userManager)

关于scala - Akka Siblings 递归 ActorRef 要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41183187/

相关文章:

java - 应用设计模式减少代码重复

scala - Akka HTTP 是否适用于 Akka Typed?

java - akka-persistence 与 mysql 数据库

scala - 为什么授权指令在它应该保护的代码之后执行?

scala - 在 SBT 中,您如何覆盖 compile 以运行任意代码?

c++ - C++中的“Poor Man'反射”(又名自下而上的反射)

java - akka 组合多个 future 列表而不阻塞

java - 从私有(private)和公共(public) maven/sbt Artifact 存储库中获取依赖项

java - Scala 中的类、对象、特征、密封特征

java - DAO 可以使用本身封装了 dataSource 对象的对象吗?