在Akka.net中未收到异常终止后

时间:2019-05-27 11:31:03

标签: akka.net

我有两个演员(父母和孩子),我使用SupervisorStrategy.StoppingStrategyWatch来处理错误。但是问题在于,孩子死亡时,父母没有收到Terminated消息。

以下是验证我的问题的简单测试。

    [Fact]
    public void ExceptionTest()
    {
        var child = Sys.ActorOf(Props.Create(() => new FooActor(), SupervisorStrategy.StoppingStrategy), "Name");
        Watch(child);
        child.Tell("Some message");
        ExpectMsg<Terminated>(); // This will not occur.
    }

    public class FooActor : ReceiveActor
    {
        public FooActor()
        {
            ReceiveAny((e) =>
            {
                // Crashes on every message.
                throw new Exception();
            });
        }
    }

我想要的是,当孩子遇到无法处理的错误时,正在看着孩子的父母应该得到Terminated。我该怎么办?

当我发送PoisonPill而不是抛出Exception时,效果很好。

1 个答案:

答案 0 :(得分:1)

测试中的参与者似乎是使用重新启动监督策略创建的,因此在发生异常时不会杀死参与者。我找不到改变测试主管策略的方法。因此,我编写此代码是为了在测试中创建参与者,而无需编写监督人员策略,而不必编写“真正的”包装参与者。

    [Fact]
    public async Task ExceptionTest()
    {
        var actor = await CreateActorWithStoppingStrategy(Props.Create(() => new AsGoodAsDead()));

        Watch(actor);

        actor.Tell("Death");

        ExpectTerminated(actor);
    }

    private async Task<IActorRef> CreateActorWithStoppingStrategy(Props props)
    {
        IActorRef child = null;
        Action<IActorDsl> actor = d =>
        {
            d.Strategy   = SupervisorStrategy.StoppingStrategy;
            d.OnPreStart = context => child = context.ActorOf(props);
            d.ReceiveAny((o, context) => context.Sender.Tell("ready"));
        };
        var parent = Sys.ActorOf(Props.Create(() => new Act(actor)));
        await parent.Ask("ready?");
        return child;
    }

    public class AsGoodAsDead : UntypedActor
    {
        protected override void OnReceive(object message)
        {
            throw new Exception();
        }
    }

您所写的以下行将为孩子提供停止监督策略,这意味着当事情发生时,孩子的孩子将被停止。

    var child = Sys.ActorOf(Props.Create(() => new FooActor(), SupervisorStrategy.StoppingStrategy), "Name");