【问题标题】:What is the correct way to resolve an actor解决演员的正确方法是什么
【发布时间】:2016-10-18 18:58:52
【问题描述】:

我有 1000 个订单,我想为每个唯一的 orderid 创建一个演员。什么是安全地创建这些演员的最佳方法,同时保证每个唯一的 orderid 我只有一个?

我尝试先使用 ActorSelection,然后如果找不到具有该 ID 的演员,我会使用 ActorOf 创建一个新的,但是当开始批量处理时,我会得到很多 ActorNotFoundException ,然后当我尝试使用 ActorOf 失败并出现 InvalidActorNameException。

例子:

try
{
    actorRef = await actorSelection.ResolveOne(TimeSpan.FromMilliseconds(3000));
}
catch (ActorNotFoundException)
{
    actorRef = Actor.EwmsActorSystem.ActorOf<T>(actorId);
}

【问题讨论】:

  • 我会以不同的方式解决它。将所有消息发送给维护 orderId -> actorRef 映射的单个 actor,对于每个订单检查是否已经创建了一个 actor(在映射中查找),如果是,则将消息发送给这个 actorRef。否则创建一个新的actor,将其保存在地图中并将消息发送到创建的actorRef。您也可以转发消息而不是发送消息。
  • Map 和.net 中的字典一样,对吧?我正在考虑存储 IActorRefs,但不确定这是否是好的做法。
  • 就我的 .net 知识而言,我认为是的,Map 是一个字典。
  • 我经常看到将 ActorRefs 保存在地图中,此时每个 Actor 都应该处理领域问题的特定部分,所以我认为这不是一种不好的做法
  • 不久前有人在 SO 上询问过 identical question

标签: c# akka akka.net


【解决方案1】:

您应该使用Entity Per Child Pattern,即有一个actor,它根据实体ID 生成子actor。您可以在 World Crawler 示例中查看 example

简而言之,它应该是这样的:

var child = Context.Child(entityId.ToString());

if (child == ActorRefs.Nobody)
    child = Context.ActorOf(...); // spawn child actor here

child.Tell(message);

在子actors上设置一个ReceiveTimeout也是一个很好的做法,当它们空闲一段时间时将它们杀死。

【讨论】:

  • 感谢您的提示。我将更新我的代码并进行测试。
  • @Gigi:我想我应该将创建演员必须的名称设为显式而不是隐式。干杯。
猜你喜欢
  • 2012-10-10
  • 2010-10-10
  • 2013-05-06
  • 1970-01-01
  • 2016-11-25
  • 2013-10-27
  • 2014-04-08
  • 1970-01-01
  • 2015-03-14
相关资源
最近更新 更多