簡體   English   中英

AKKA.Net:如何在 Actor Restart 上從主管向孩子發送消息

[英]AKKA.Net: How to send message from supervisor to child on Actor Restart

考慮到這段代碼:

public class ParentActor : ReceiveActor
{
    public ParentActor()
    {
        for( i = 1; i <= 5; i++)
    
        var childActor = Context.ActorOf<ChildActor>($"Child{i}");
        childActor.Tell( new LoadData(i));
        
    }
}

public class ChildActor : ReceiveActor
{
    
    public ChildActor()
    {
        Receive<LoadData>(msg => 
        {
            var data = SomeRiskyOverNetworkCall(msg.AccountId);
        });
    }
}

public class LoadData
{
    
    public int AccountId { get; }
    
    public LoadData(int accountId)
    {
        AccountId = accountId;
    }

}

子actor執行一些有時會失敗的危險操作調用正在使用一些參數,這些參數是在創建子actor之后從父/監督actor傳遞的。

如何“監督”這種情況? 我需要在重啟后處理相同的LoadData (具有相同參數)消息。

您可以將預重啟掛鈎與一些主管策略一起使用。 下面是一個簡單的例子。 https://getakka.net/articles/actors/fault-tolerance.html#creating-a-supervisor-strategy

using System;
using System.Threading;
using Akka.Actor;

namespace AkkaConsoleSimple
{
    public class Start
    {
        public Start()
        {
            
        }
        
    }

    public class DoSomething
    {
        public DoSomething(int who)
        {
            Who = who;
        }
        public int Who { get; private set; }
    }

    public class FailedMessage
    {
        public FailedMessage(object who)
        {
            Who = who;
        }
        public object Who { get; private set; }
    }

    public class Child : ReceiveActor
    {
        public Child()
        {
            Receive<DoSomething>(msg =>
            {
                Console.WriteLine($"getting message no {msg.Who}");
                if (msg.Who == 10)
                {
                    throw new StackOverflowException();
                }
                
            });
        }

        protected override void PreRestart(Exception cause, object message)
        {
            Sender.Tell(new FailedMessage(message));
            Self.Tell(message);
            base.PreRestart(cause, message);
        }
    }
    public class Parent : ReceiveActor
    {
        public Parent()
        {
            Receive<Start>(greet =>
            {
                var child = Context.ActorOf<Child>();
                for (int i = 0; i < 11; i++)
                {
                    var msg = new DoSomething(i);
                    child.Tell(msg);
                }
               
            });

            Receive<FailedMessage>(failed => Console.WriteLine(failed.Who));
        }
        protected override SupervisorStrategy SupervisorStrategy()
        {
            return new OneForOneStrategy(
                maxNrOfRetries: 10,
                withinTimeRange: TimeSpan.FromMinutes(1),
                localOnlyDecider: ex =>
                {
                    switch (ex)
                    {
                        case StackOverflowException ae:
                            return Directive.Restart;
                        default:
                            return Directive.Escalate;
                    }
                });
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var system = ActorSystem.Create("MySystem");
            var greeter = system.ActorOf<Parent>("parent");
            greeter.Tell(new Start());

            Console.Read();
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM