Akka.net正在等待多条数据
本文关键字:数据 在等待 net Akka | 更新日期: 2023-09-27 18:19:43
这是我遇到的一个常见场景,其中我有两个(或多个)参与者异步获取一些数据,然后我需要在它们全部完成时执行操作。
这样做的常见模式是什么?
下面是一个简化的例子。
public MasterActor : ReceiveActor
{
public MasterActor()
{
Initialize();
}
public void Initiaize()
{
Receive<DoSomeWork>(_ =>
{
var actor1 = Context.ActorOf(Props.Create(() => new Actor1());
var actor2 = Context.ActorOf(Props.Create(() => new Actor2());
// pretend these actors send responses to their senders
// for sake of example each of these methods take between 1 and 3 seconds
actor1.Tell(new GetActor1Data());
actor2.Tell(new GetActor2Data());
});
Receive<Actor1Response>(m =>
{
//actor 1 has finished it's work
});
Receive<Actor2Response>(m =>
{
//actor 2 has finished it's work
});
}
}
为此,我向MasterActor
发送了一条DoSomeWork
消息。
当我同时拥有Actor1Response
和Actor2Response
时,执行操作的常用方法是什么。
我真的不想在每个接收处理程序中都有逻辑来检查另一个是否完成或类似的事情。我想我想的是类似于Task.WaitAll()
方法的东西。
我只是错误地解决了这个问题吗?我需要用不同的方式改写演员吗?
任何常见的模式或解决方案都会很棒。
常见的解决方案是附加请求和响应消息共享的某种关联id-由于actor同步处理消息,因此可以取消选中int/long计数器。
您只需将关联id存储在调用方内部的某个数据结构(比如set)中,当收到响应时,从set中删除它的关联id。WaitAll
在set为空或超时时基本结束。
您可以使用Context.SetReceiveTimeout(timeout)
设置超时,这样actor将在一段时间没有收到任何消息后向自己发送ReceiveTimeout
方法。
这种行为非常通用,可以很容易地抽象出来。
最简单的方法是在每个子级回复时增加master的"投票"计数。当投票==孩子计数时,你就完了。
您可以将其扩展为只计算每个子级的第一条消息,或每个子级特定的消息,但这一切最终都归结为计数。