2016-01-30 61 views
1

我正在为一个生产项目创建一个Akka.NET概念证明,但我正面临查询概念理解问题。Akka.NET有效地查询演员

情况如下: CoordinatorActor有一个数千个列表Hotel-Actors

我想查询所有具有特定日期房间的酒店的所有Hotel-Actors

当然我可以通过它们进行foreach并发送.Ask<>请求具体日期。持有所有任务的参考,并执行Task.WhenAll(requests)。但那感觉有点不自然。

我也可以在一次(ActorSelection或路由器)与特定日期的所有酒店请求发送广播消息,但我不知道他们什么时候所有Tell消息回应道。

有没有人有建议如何解决这个问题?

+0

你能详细说明真实情况吗?这样可以更容易推荐合适的解决方案。 – usr

+0

该场景是一个有很多酒店的预订网站,用户应该在特定的日期查看可用的酒店。酒店可用的标准相当复杂且充满活力。 也应该只能像特定区域的酒店一样进行子选择。 – Max

+0

酒店的“数据库”甚至是阿卡的好例子吗?看起来像一些正常的数据结构将是足够的,并具有较少的开销。如果你需要一直询问所有酒店,那么每家酒店的一名演员似乎也值得怀疑。 – usr

回答

3

是的,你的感觉就在这里。使用询问参与者之间的通信被认为是非常低效的 - 主要是因为每个询问需要分配单独的消息监听器。

第一个好问题是:你是否需要等待他们全部回复?也许回应可以在他们到来时发出。

如果您在回复前需要收集所有数据,则需要对某些消息进行计数,以确保其中的某些消息是否仍然存在 - 在这种情况下,使用ActorSelection是不可行的。您需要计数器或可能与每封邮件相关联的标识符列表,而它们甚至可以是普通数字,通常IActorRef更容易处理。

下面您可以看到Aggregator演员的简化示例,该演员可以为此特定任务创建 - 它将自动返回收到的所有回复,并在没有更多消息等待或发生超时时自动停止。

class Aggregator<T> : ReceiveActor 
{ 
    private IActorRef originalSender; 
    private ISet<IActorRef> refs; 

    public Aggregator(ISet<IActorRef> refs) 
    { 
     this.refs = refs; 
     // this operation will finish after 30 sec of inactivity 
     // (when no new message arrived) 
     Context.SetReceiveTimeout(TimeSpan.FromSeconds(30)); 
     ReceiveAny(x => 
     { 
      originalSender = Sender; 
      foreach (var aref in refs) aref.Tell(x); 
      Become(Aggregating); 
     }); 
    } 

    private void Aggregating() 
    { 
     var replies = new List<T>(); 
     // when timeout occurred, we reply with what we've got so far 
     Receive<ReceiveTimeout>(_ => ReplyAndStop(replies)); 
     Receive<T>(x => 
     { 
      if (refs.Remove(Sender)) replies.Add(x); 
      if (refs.Count == 0) ReplyAndStop(replies); 
     }); 
    } 

    private void ReplyAndStop(List<T> replies) 
    { 
     originalSender.Tell(new AggregatedReply<T>(replies)); 
     Context.Stop(Self); 
    } 
} 
+0

感谢您的完美答案和代码!事实上,我需要确保所有演员返回,否则结果不能保证正确。我发现,酒店行业人数(1M)上的Ask <>确实可能会导致内存不足异常。 我已经使用数据库来查询条件(面积,星星等)上的酒店,并选择ActorPath(女巫是静态的)的字符串。通过这种方式,只有相关的酒店行业者被要求提供。 Btw也许这个代码是不安全的并行请求? – Max

+1

此示例假定您为每个聚合查询创建一个actor。它会自动关闭。 当涉及到正确性保证时,这取决于用例 - 不完整的答案并不总是一个错误的答案,即从酒店搜索的角度来看,显示120个正确答案中的100个仍然比显示具有“对不起,我们无法满足您的要求“。 – Horusiath