akkadotnet / akka.net

Canonical actor model implementation for .NET with local + distributed actors in C# and F#.
http://getakka.net
Other
4.69k stars 1.04k forks source link

Routers seem ignore supervision strategy #996

Closed simonlaroche closed 9 years ago

simonlaroche commented 9 years ago

If I provide a supervision strategy to a router config it never gets called on an exception from a routee.

It seems that the strategy gets overwritten be the default strategy in ActorBase.

Failing test:


public class RouterSupervisorSpec : AkkaSpec
    {
        #region Killable actor

        class KillableActor : ReceiveActor
        {
            private readonly IActorRef TestActor;

            public KillableActor(IActorRef testActor)
            {
                this.TestActor = testActor;
                this.Receive<string>(s => s == "go away", s =>
                    {
                        throw new ArgumentException("Goodbye then!");
                    });
            }
        }

        #endregion

        #region Tests

        [Fact]
        public void Routers_must_use_provided_supervisor_strategy()
        {
            var router = this.Sys.ActorOf(Props.Create(() => new KillableActor(this.TestActor))
                .WithRouter(
                new RoundRobinPool(1, null, new OneForOneStrategy(
                    exception =>
                    {
                        this.TestActor.Tell("supervised");
                        return Directive.Stop;
                    }), 
                    null)), 
                    "router1");

            router.Tell("go away");

            this.ExpectMsg("supervised", TimeSpan.FromSeconds(2));
        }

        #endregion
    }
Aaronontheweb commented 9 years ago

Good find! would you mind submitting this failing test as a PR?

simonlaroche commented 9 years ago

Done

rogeralsing commented 9 years ago

I've found the reason for it.

        private ActorBase NewActor()
        {
            PrepareForNewActor();
            ActorBase instance=null;
            UseThreadContext(() =>
            {
                _state = _state.ClearBehaviorStack();

       //the router actor is created here, with the correct supervisor strategy

                instance = CreateNewActorInstance();

       //which is then overwritten by the props supervisor strategy (which doesnt exist in JVM)

                instance.SupervisorStrategyInternal = _props.SupervisorStrategy;
            });
            return instance;
        }
rogeralsing commented 9 years ago

I've made a PR for this #1000