2016-02-27 2 views
2

Я стараюсь, чтобы стратегия супервизора работала. Вот иллюстрация сценария.Не удается получить стратегию супервизора для работы в Akka.NET

A diagram of a demo app the implements a SupversiorStrategy

У меня есть актер, FloorTrader что на OnReceive (объект сообщения), создает FederalRegulator Актер:

var regulator = Context.ActorOf(Props.Create(() => new FederalRegulator("EAST_USA",trade)), "EastFedRegulator"); 

Затем, после строительства, FederalRegulator создает StateRegulators

public class FederalRegulator : RegulatorBase 
{ 
    public FederalRegulator(string name, Trade trade) : base(name, trade) 
    { 

     StateRegulate(trade); 
    } 

    protected override void OnReceive(object message) 
    { 
     var msg = message as string; 

     if(!string.IsNullOrEmpty(msg) && msg.ToUpper().Equals("STOP"))throw new TradeException("No Trading Today"); 
    } 

    private static void StateRegulate(Trade trade) 
    { 
     Context.ActorOf(Props.Create(() => new StateRegulator("NY", trade)), "NYRegulator"); 
     Context.ActorOf(Props.Create(() => new StateRegulator("MA", trade)), "MARegulator"); 
     Context.ActorOf(Props.Create(() => new StateRegulator("CT", trade)), "CTRegulator"); 
    } 
} 

Все регуляторы испускают поведение Console.Write() при построении следующим образом:

public abstract class RegulatorBase : UntypedActor 
{ 
    protected RegulatorBase(string name, Trade trade) 
    { 
     Name = name; 
     Trade = trade; 
     Regulate(Name, Trade); 
    } 

    public string Name { get; private set; } 
    public Trade Trade { get; private set; } 

    protected void Regulate(string name, Trade trade) 
    { // Create a timer 
     var myTimer = new System.Timers.Timer(); 
     // Tell the timer what to do when it elapses 
     myTimer.Elapsed += delegate { Console.WriteLine("{0} is regulating the trade for, {1} ", Name,Trade.Ticker); }; 
     // Set it to go off every 1/2 second, 
     myTimer.Interval = 500; 
     // And start it   
     myTimer.Enabled = true; 

    } 

    protected override void OnReceive(object message) 
    { 
     //put stuff in later 
    } 
} 

Реализация SupervisionStrategy() в FloorTrader актера:

protected override SupervisorStrategy SupervisorStrategy() 
{ 
    return new OneForOneStrategy(
     0, // maxNumberOfRetries 
     TimeSpan.FromSeconds(1), // duration 
     x => 
      { 
      if (x is TradeException) 
       { 
        Console.WriteLine("---BLOW UP-----"); 
        return Directive.Stop; 
       } 
      return Directive.Restart; 
      }); 
} 

Когда FederalRegulator получает сообщение СТОП, он запускает пользовательское исключение, TradeException, как показано выше в коде FederalRegulator.

Выход перед костром сообщение СТОП является ожидаемым:

EAST_USA is regulating the trade for, HP 
MA is regulating the trade for, HP 
NY is regulating the trade for, HP 
CT is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 
MA is regulating the trade for, HP 
CT is regulating the trade for, HP 
NY is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 
CT is regulating the trade for, HP 
NY is regulating the trade for, HP 
MA is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 
MA is regulating the trade for, HP 
CT is regulating the trade for, HP 
NY is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 
MA is regulating the trade for, HP 
CT is regulating the trade for, HP 
NY is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 
MA is regulating the trade for, HP 
CT is regulating the trade for, HP 
NY is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 

Мое мышление является то, что, поскольку я использую OneForOneStrategy, когда я сгореть сообщение СТОП, в FederalRegulator актера, один излучающий, EAST_USA is regulating the trade for, HP должен остановиться, но его дети, ГосударственныеРегуляторы должны продолжать идти.

ОДНАКО, когда я запускаю сообщение STOP, используя: regulator.Tell("STOP"); Торговое исключение бросается, но FederalRegulator продолжает излучать. Кроме того, я получаю сообщения «Мертвого письма»:

EAST_USA is regulating the trade for, HP 
CT is regulating the trade for, HP 
NY is regulating the trade for, HP 
MA is regulating the trade for, HP 
---BLOW UP----- 
[ERROR][2/27/2016 12:18:49 AM][Thread 0011][akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator] No Trading Today 
Cause: AkkaNetDemo.Exceptions.TradeException: No Trading Today 
    at AkkaNetDemo.Regulators.FederalRegulator.OnReceive(Object message) in c:\Users\Bob\Documents\GitHub\AkkaNetDemo\AkkaNetDemo\Regulators\FederalRegulator.cs:line 20 
    at Akka.Actor.UntypedActor.Receive(Object message) 
    at Akka.Actor.ActorBase.AroundReceive(Receive receive, Object message) 
    at Akka.Actor.ActorCell.ReceiveMessage(Object message) 
    at Akka.Actor.ActorCell.Invoke(Envelope envelope) 
[INFO][2/27/2016 12:18:49 AM][Thread 0013][akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator] Message DeathWatchNotification from akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator to akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator was not delivered. 1 dead letters encountered. 
[INFO][2/27/2016 12:18:49 AM][Thread 0012][akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator] Message DeathWatchNotification from akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator to akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator was not delivered. 2 dead letters encountered. 
[INFO][2/27/2016 12:18:49 AM][Thread 0011][akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator] Message DeathWatchNotification from akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator to akka://TradingSystem/user/MyBroker/SellFloorTrader/EastFedRegulator was not delivered. 3 dead letters encountered. 
EAST_USA is regulating the trade for, HP 
CT is regulating the trade for, HP 
MA is regulating the trade for, HP 
NY is regulating the trade for, HP 
Enter Trade: EAST_USA is regulating the trade for, HP 
CT is regulating the trade for, HP 
MA is regulating the trade for, HP 
NY is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 
CT is regulating the trade for, HP 
NY is regulating the trade for, HP 
MA is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 
CT is regulating the trade for, HP 
NY is regulating the trade for, HP 
MA is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 
CT is regulating the trade for, HP 
NY is regulating the trade for, HP 
MA is regulating the trade for, HP 
EAST_USA is regulating the trade for, HP 

Может кто-нибудь помочь мне разобраться в ошибках моих путей. Из того, что я читал, когда вы используете OneForOneStrategy(), родитель должен остановиться, а дети продолжатся.

Заранее благодарен!

ответ

2

Факт, что вы получили сообщение мертвыми буквами, означает, что актер был остановлен правильно.

Однако, я думаю, что основная проблема здесь может быть вызвана тем фактом, что вы используете класс Timer - который является ресурсом одноразового использования - без его утилизации и отмена делегатов, что может привести к тому, после того, как актер мертв.

В общем, вы, вероятно, не хотите использовать таймеры, так как Akka.NET дает вам бесплатную функцию scheduler, которая поддерживает отправку сообщений или выполнение действий с задержкой или повторяемо. Он также поддерживает отмену.

также:

Мое мышление является то, что, поскольку я использую OneForOneStrategy, когда я сгореть сообщение СТОП, в FederalRegulator актера, один излучающий, EAST_USA регулирует торговлю для НР следует прекратить, но его дети, государственные регенты должны продолжать идти.

В случае OneForOneStrategy результирующая директива будет применена к актеру, но это означает, что она также будет иметь последствия для ее детей. Если актер будет остановлен, дети тоже будут, так как они не могут жить без родителя. Разница между «один-к-одному» и «все-к-одному» заключается в том, что правило «все-к-одному» работает горизонтально (в случае отказа актера оно будет применяться ко всем его братьям и сестрам).

Смежные вопросы