嵌套请求的正确模式
Proper pattern for nested asks
我有一个 actor 有很多 children,我正在查询它以获取其 children 中的数据聚合。此操作可能需要几秒钟。
我正要这样做,但感觉完全错了。 handle 方法由 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()));
}
我有一些想法,但想听取一些意见,因为我真的不想重新发明一个 20 边形的轮子。
我担心对 Sender
的引用以及当我最终调用 Tell
时它将指向什么,因为它是静态调用。
我最终使用了 Task.WhenAll
延续,但仍然不相信这是正确的 Akka 方式 - 这就是这里的重点。我可以让它工作,我只是想知道最佳实践选项。
一般来说,Ask
应该只用于与来自外部服务的 actor 的通信,几乎从不用于两个 actor 之间的通信。它比使用 Tell
贵很多。另一个问题是使用 Task.WaitAll
,它实际上会阻塞当前线程,直到所有响应都到达,这对性能也很不利,并可能最终导致死锁。
类似的 thread 已在 github 上讨论过。
聚合问题的一般解决方案是:
- 为聚合过程创建一个单独的参与者。
- 用演员列表初始化它,它应该从演员那里收集数据并记住演员,收集的结果会通知演员。
- 为每个演员发送request/query。
- 处理每个 request/query 响应,将其聚合到单独的数据结构中,并从等待的参与者列表中删除一个发件人。
- 一旦没有演员等待 - 发送结果并停止当前演员(负责数据聚合的演员)。
- 附加
ReceiveTimeout
机制以防万一,当由于某种原因并非所有参与者都能够在合理的时间内做出响应时 - 当超时发生时,您可能 return 失败或到目前为止收集的响应列表.
PS:不要使用 TypedActor - 它对性能也不好,is/will 会过时。
我有一个 actor 有很多 children,我正在查询它以获取其 children 中的数据聚合。此操作可能需要几秒钟。
我正要这样做,但感觉完全错了。 handle 方法由 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()));
}
我有一些想法,但想听取一些意见,因为我真的不想重新发明一个 20 边形的轮子。
我担心对 Sender
的引用以及当我最终调用 Tell
时它将指向什么,因为它是静态调用。
我最终使用了 Task.WhenAll
延续,但仍然不相信这是正确的 Akka 方式 - 这就是这里的重点。我可以让它工作,我只是想知道最佳实践选项。
一般来说,Ask
应该只用于与来自外部服务的 actor 的通信,几乎从不用于两个 actor 之间的通信。它比使用 Tell
贵很多。另一个问题是使用 Task.WaitAll
,它实际上会阻塞当前线程,直到所有响应都到达,这对性能也很不利,并可能最终导致死锁。
类似的 thread 已在 github 上讨论过。
聚合问题的一般解决方案是:
- 为聚合过程创建一个单独的参与者。
- 用演员列表初始化它,它应该从演员那里收集数据并记住演员,收集的结果会通知演员。
- 为每个演员发送request/query。
- 处理每个 request/query 响应,将其聚合到单独的数据结构中,并从等待的参与者列表中删除一个发件人。
- 一旦没有演员等待 - 发送结果并停止当前演员(负责数据聚合的演员)。
- 附加
ReceiveTimeout
机制以防万一,当由于某种原因并非所有参与者都能够在合理的时间内做出响应时 - 当超时发生时,您可能 return 失败或到目前为止收集的响应列表.
PS:不要使用 TypedActor - 它对性能也不好,is/will 会过时。