Обработка исключений, возникающих, когда Akka.NET Actor отвечает на асинхронный запрос из потока - PullRequest
0 голосов
/ 07 декабря 2018

При интеграции актера с потоком Akka.NET, как описано в документации по Akka.NET , я столкнулся с проблемой обработки исключений.Если актер просто выдает исключение, то Акка проглатывает его, и мне приходится ждать, пока тайм-аут не сработает, чтобы о нем сообщили.

Я предполагаю, что это потому, что актер не отправляет сообщениеобратно в поток.Используя подход старой школы, заключающийся в использовании большого try-catch на границе потока, я могу добавить исключение в сообщение для отправителя, что позволит ему преодолеть тайм-аут и продолжить.

Пример кода ниже,Насколько я могу судить, я не могу создать стратегию супервизора, которая позволит потоку обрабатывать исключение субъекта.Какой лучший способ справиться с этим?

// Run app with argument "straightThrow" or "catchAndHandle"
class Bleurgher : ReceiveActor
{
    public Bleurgher()
    {
        Receive<string>(s => 
        {
            switch (s) {
                case "straightThrow":
                    throw new Exception("Bleurgh");
                    break;
                case "catchAndHandle":
                    try
                    {
                        throw new Exception("Bleurgh");
                    }
                    catch (Exception x)
                    {
                        Console.WriteLine($"Exception : {x.Message}");
                        Sender.Tell(new Akka.Actor.Status.Failure(x));
                    };
                    break;
            }

        });
    }

    public static Akka.Actor.Props Props()
    {
        return Akka.Actor.Props.Create<Bleurgher>();
    }
}

class Program
{
    static void Main(string[] args)
    {
        using (var system = ActorSystem.Create("cast"))
        using (var materializer = system.Materializer())
        {
            var data = new List<string>(args);

            var bleurgher = system.ActorOf(Bleurgher.Props());

            var source = Source.From(data);
            var sink = Sink.ForEach<string>(s => Console.WriteLine(s));

            var runnable = source
                .SelectAsync(1, o => bleurgher.Ask(o, TimeSpan.FromSeconds(5)))
                .Select(o => (o.ToString()))
                .ToMaterialized(sink, Keep.Right);

            runnable.Run(materializer).Wait();
        }
    }
}
...