在AKKA中的Receive方法中创建子actor是否有意义?

时间:2016-09-06 21:18:56

标签: .net akka akka.net actor-model

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

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

3 个答案:

答案 0 :(得分:3)

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

这方面的一个主要例子是Child Per Entity pattern,您可以在其中为每个实体ID创建一个actor。因此,如果您收到之前未收到过新ID的邮件,则需要启动新的儿童演员。

您可以看到how the web crawler sample does this。虽然第一个诱惑是维护一个id to child actor的词典,但事实证明这甚至都不是必需的。正如网络抓取工具示例所做的那样,您可以检查演员Children以确定其是否已经拥有该子女。

当你动态创建儿童演员时,你可能想给他们一个ReceiveTimeout,以确保他们永远不会泄漏记忆。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

动态创建actor的另一个示例是描述了here的Extra和Cameo模式以及源代码here

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

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

底线:根据请求创建演员可以让您更好地隔离工作单元,保持"入口点"演员不那么忙,并提供更好的范围日志(这对理解分布式系统行为非常重要)。