1

让我们假设我需要将一些子流程委托给子角色。我可以在 Actor 初始化期间创建子 Actor(在 AKKA.NET 中称为 PreStart)。如果我需要多个子角色并行运行,我可以使用 AKKA 路由器。我认为这是推荐的方法。

但是,我也可以在 Receive-method 中创建子 Actor,并让对 IActorRef 实例的引用具有 Receive-method 的本地范围。这种方法有意义吗?它会比上述情况提供任何优势吗?

4

3 回答 3

3

在消息处理程序中创建子 Actor 非常有意义,尤其是当您无法先验创建它们时,因为您根据传入数据动态创建它们。

一个典型的例子是Child Per Entity 模式,您可以在其中为每个实体 id 创建一个参与者。因此,如果您收到一条您以前没有收到过的带有新 id 的消息,您将需要启动一个新的子 actor。

您可以看到网络爬虫示例是如何做到这一点的。虽然第一个诱惑是为子演员维护一个 id 字典,但事实证明这甚至没有必要。正如网络爬虫示例所做的那样,您可以检查参与者Children以确定它是否已经拥有该孩子。

当您动态创建子演员时,您可能希望给他们一个ReceiveTimeout以确保他们不会因为永远存在而泄漏内存。

于 2016-09-08T13:06:41.607 回答
1

另一个动态创建演员的例子是这里描述的 Extra 和 Cameo 模式以及这里的源代码

Cameo 模式的基本思想是在实际工作人员(Cameos)的前面有一个响应式外观。它与路由器不同,因为 Facade 不在响应路径上,它将所有相关上下文交给 Cameo 并让它完成工作并将结果直接传达给(原始工作的)发送者。

额外的模式是相同的,但有匿名演员。Cameo actor 更好,因为它提供了更好的日志(具有可读的 actor 名称)并更好地构建了代码。此外,关闭门面演员的状态也更加困难。

底线:为每个请求创建参与者可以让您更好地隔离工作单元,让“入口点”参与者不那么忙,并提供更好的范围日志(这对于理解分布式系统行为可能非常重要)。

于 2016-09-09T18:12:51.590 回答
1

是的。例如,如果收到的每条消息都开始某个有状态的过程,那么您将创建子角色来处理这个过程。这些子角色可能需要响应来自其他角色的其他消息。然后可能会有一条最终消息告诉该过程完成。您可以将 IActorRef 作为消息的一部分传递,因此本地范围的概念不一定适用。

于 2016-09-07T06:03:43.297 回答