Proper pattern for nested asks

我的未来我决定 提交于 2019-12-05 06:52:18

问题


I have an actor with many children and I am querying it to get an aggregate of the data in its children. This operation could take a few seconds.

I was about to do this and it feels so completely wrong. The handle method is called by an Ask<>.

public void Handle(Message message)
{
    var children = Context.GetChildren();
    var tasks = new List<Task<Result>>();

    foreach (var child in children)
    {
        var t = child.Ask<Result>(new Query);
        tasks.Add(t);
    }

    Task.WaitAll(tasks.ToArray()); // Gah!
    // do some work
    Sender.Tell(new Response(new Results()));
}

I have a few ideas, but wanted to get some input as I don't really want to reinvent a 20 sided wheel.

I am worried about the reference to Sender and what it will be pointing at when I finally get to call Tell on it as it is a static call.

I've ended up using the Task.WhenAll continuation, but still not convinced it's the right Akka way - which is the point here. I can make it work, I just want to know the best practice options.


回答1:


In general Ask should be used only for the communication with an actor from external services, almost never between two actors. It's a lot more expensive than using Tell. Additional problem is to use Task.WaitAll which actually blocks current thread until all responses will arrive, which is also bad for performance and may end up with deadlock.

Similar thread was already discussed on github.

General solution for aggregation problems is:

  • Create a separate actor for aggregation process.
  • Initialize it with list of actors, it is supposed to collect data from and remember the actor, which will be informed with collected result.
  • Send request/query for each actor.
  • Handle each request/query response, aggregating it in separate data structure and remove a sender from the list of awaited actors.
  • Once there is no actor to await for - send a result and stop current actor (the one responsible for data aggregation).
  • Attach ReceiveTimeout mechanism in case, when for some reason not all actors are able to respond in reasonable time - when timeout will hit, you may return failure or list of responses collected so far.

PS: Don't use TypedActor - it's also bad for performance and is/will become obsoleted.



来源:https://stackoverflow.com/questions/32424776/proper-pattern-for-nested-asks

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!