Я новичок в программировании на proto.actor/actor, и мне интересно, возможно ли добиться такого поведения:
Актер A запрашивает актера B с помощью асинхронной команды - он должен ждать ответа для достижения модели запрос / ответ, но с использованием задач.
Актер B использует HTTP-запрос, так что это будет некоторая асинхронная операция ввода-вывода, поэтому я не хочу, чтобы она была заблокирована для других актеров в это время, поэтому, когда 10 актеров будут спрашивать его одновременно, каждый запрос будет поставлен в очередь, но пока он первый запрос ожидает обработки, второй должен получить возможность продолжить. После того, как первый запрос будет завершен, он должен иметь приоритет в очереди и получить ответ субъекту А.
Как получить этот поток?
Например, у меня есть 3 клиента, которые запрашивают у службы некоторые данные, сервисный звонок занимает 5 секунд, и большую часть этого времени служба тратит на ввод-вывод. В текущей реализации у нас есть всего 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;
}
}