2

我正在尝试监督策略工作。这是该场景的说明。

实现 SupversiorStrategy 的演示应用程序图

我有一个演员 FloorTrader,它在 OnReceive(object message) 时创建一个 FederalRegulator Actor:

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");
    }
}

所有 Regulators 在构造时都会发出 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
     }
}

FloorTrader 角色中 SupervisionStrategy() 的实现是:

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 收到 STOP 消息时,它会触发自定义异常 TradeException,如上面 FederalRegulator 代码中所示。

触发 STOP 消息之前的输出是预期的:

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,所以一旦我触发了 STOP 消息,FederalRegulator 演员,即发射者,EAST_USA is regulating the trade for, HP应该停止,但它的孩子,StateRegulators 应该继续前进。

但是,当我使用以下命令触发 STOP 消息时:regulator.Tell("STOP"); TradeException 被抛出,但 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

任何人都可以帮助我找出我的方式的错误。根据我一直在阅读的内容,当一个人使用 a 时OneForOneStrategy(),父母应该停止,孩子们会继续。

4

1 回答 1

2

您收到死信的事实意味着该演员已正确停止。

但是我认为,这里的主要问题可能是由于您正在使用Timer类 - 这是一种一次性资源 - 没有处理它并取消固定代表,这可能导致即使在演员死后也会发出控制台写入.

一般来说,您可能不想使用计时器,因为 Akka.NET 为您提供了免费的调度程序功能,它支持以延迟或可重复的方式发送消息或执行操作。它也支持取消。

还:

我的想法是,因为我使用的是 OneForOneStrategy,所以一旦我发出 STOP 消息,FederalRegulator 演员,即发出 , EAST_USA 正在监管贸易,HP 应该停止,但它的孩子,StateRegulators 应该继续前进。

在 的情况下OneForOneStrategy,生成的指令将应用于一个演员,但这意味着它也会对它的孩子产生影响。如果演员被阻止,孩子也会被阻止,因为他们不能没有父母。one-for-one 和 all-for-one 之间的区别在于,all-for-one 规则水平工作(如果参与者失败,它将应用于它的所有兄弟姐妹)。

于 2016-02-27T07:49:50.907 回答