我是proto.actor/actor编程的新手,我想知道是否可以实现此行为:
演员A通过异步命令询问演员B –他应该等待响应以实现请求/响应模型,但要使用任务。 演员B使用的是HTTP请求,因此这将是一些异步IO操作,因此我不希望这次被其他演员阻止,因此当10个演员在同一时间询问他时,每个请求都将排队,但是在第一次请求正在等待第二个过程,应该有机会继续。首次请求完成后,它应该在队列中具有优先级并获得对参与者A的响应。
如何获得此流程?
例如,我有3个客户端向服务询问一些数据,服务呼叫花费5秒钟,而大部分时间服务花费在IO上。在当前的实现中,我们所有请求的总时间为15秒,但我希望此过程大约需要5-6秒
public static class ProtoTest
{
public static PID Service;
public static async Task Start()
{
var context = new RootContext();
var props = Props.FromProducer(() => new ClientActor());
var serviceProps = Props.FromProducer(() => new ServiceActor());
Service = context.Spawn(serviceProps);
var jobs = new List<Task>();
for (int i = 0; i < 3; i++)
{
string actorName = $"Actor_{i}";
jobs.Add(Task.Run(() =>
{
var client = context.SpawnNamed(props, actorName);
context.Send(client, new Command());
}));
}
Console.ReadLine();
}
}
public class ClientActor : IActor
{
public virtual async Task ReceiveAsync(IContext context)
{
if (context.Message is Command)
{
Console.WriteLine($"{DateTime.Now.ToLongTimeString()} START processing by {context.Self.Id}");
var result = await context.RequestAsync<string>(ProtoTest.Service, new Query());
Console.WriteLine($"{DateTime.Now.ToLongTimeString()} End processing by {context.Self.Id}");
}
return;
}
}
public class ServiceActor : IActor
{
public async virtual Task ReceiveAsync(IContext context)
{
if (context.Message is Query)
{
// this operation is taking long time so actor could handle others in this time
await Task.Delay(5000);
context.Respond("result");
}
return;
}
}
答案 0 :(得分:0)
参与者的核心原则之一是它不会并行执行多个操作。如果我正确地理解了您的问题,您可以做的是为您要并行运行的每个操作创建一个新的actor(actor很便宜,因此创建很多不是问题)。因此,如果角色A需要发送N条命令进行异步处理并接收传入的每个结果,则可以生成N个角色B1,B2 ... Bn(每个命令一个)并向每个角色发送请求。 B演员等待结果,然后回复给A演员。然后,每个响应将作为消息发送到参与者A的邮箱,并按照其完成的顺序依次处理。