让我们假设我需要将一些子流程委托给子actor。我可以在actor初始化期间创建子actor(在AKKA.NET中称为PreStart)。如果我需要多个子actor并行运行,我可以使用AKKA路由器。我认为这是推荐的方法。
但是,我也可以在Receive方法中创建子actor,并让对IActorRef实例的引用具有Receive-method的本地范围。这种方法会有意义吗?它会比上述情况提供任何优势吗?
答案 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名称)并且使代码结构更好一些。关闭门面演员的状态也很困难。
底线:根据请求创建演员可以让您更好地隔离工作单元,保持"入口点"演员不那么忙,并提供更好的范围日志(这对理解分布式系统行为非常重要)。