public void OneForOneStrategy_Should_EscalateFailureToParent() { var parentMailboxStats = new TestMailboxStatistics(msg => msg is Stopped); var strategy = new OneForOneStrategy((pid, reason) => SupervisorDirective.Escalate, 1, null); var childProps = Actor.FromProducer(() => new ChildActor()); var parentProps = Actor.FromProducer(() => new ParentActor(childProps)) .WithChildSupervisorStrategy(strategy) .WithMailbox(() => UnboundedMailbox.Create(parentMailboxStats)); var parent = Actor.Spawn(parentProps); parent.Tell("hello"); parentMailboxStats.Reset.Wait(1000); var failure = parentMailboxStats.Received.OfType <Failure>().Single(); Assert.IsType <Exception>(failure.Reason); }
public void Routers_in_general_must_set_supplied_supervisorStrategy_for_FromConfig() { var escalator = new OneForOneStrategy(e => { TestActor.Tell(e); return(Directive.Escalate); }); var router = Sys.ActorOf(FromConfig.Instance.WithSupervisorStrategy(escalator).Props(Props.Create <BlackHoleActor>()), "router1"); router.Tell(new GetRoutees()); EventFilter.Exception <ActorKilledException>().ExpectOne(() => { ExpectMsg <Routees>().Members.First().Send(Kill.Instance, TestActor); }); ExpectMsg <ActorKilledException>(); }
public void UnitTestFramework_ResolvedSupervisorStrategiesAreStored() { //arrange SupervisorStrategy parentSupervisorStrategy = new AllForOneStrategy(exception => Directive.Restart); SupervisorStrategy childSupervisorStrategy = new OneForOneStrategy(exception => Directive.Restart); UnitTestFramework <ParentActorWithSupervisorStratery> sut = UnitTestFrameworkSettings .Empty .CreateFramework <ParentActorWithSupervisorStratery>(this, Props.Create(() => new ParentActorWithSupervisorStratery(parentSupervisorStrategy, childSupervisorStrategy)), 2); //act SupervisorStrategy result = sut.ResolvedSupervisorStrategy("ChildWithParentSupervisorStrategy"); //assert result.Should().BeSameAs(parentSupervisorStrategy); }
public void WhenActorRestarted_DisposeIsCalled() { var childMailboxStats = new TestMailboxStatistics(msg => msg is Stopped); var disposeCalled = false; var strategy = new OneForOneStrategy((pid, reason) => SupervisorDirective.Restart, 0, null); var childProps = Props.FromProducer(() => new DisposableActor(() => disposeCalled = true)) .WithMailbox(() => UnboundedMailbox.Create(childMailboxStats)) .WithChildSupervisorStrategy(strategy); var props = Props.FromProducer(() => new SupervisingActor(childProps)) .WithMailbox(() => new TestMailbox()) .WithChildSupervisorStrategy(strategy); var parent = Context.Spawn(props); Context.Send(parent, "crash"); childMailboxStats.Reset.Wait(1000); Assert.True(disposeCalled); }
public void UnitTestFramework_ThrownsWhenChildHasNotBeenResolved() { //arrange SupervisorStrategy parentSupervisorStrategy = new AllForOneStrategy(exception => Directive.Restart); SupervisorStrategy childSupervisorStrategy = new OneForOneStrategy(exception => Directive.Restart); UnitTestFramework <ParentActorWithSupervisorStratery> sut = UnitTestFrameworkSettings .Empty .CreateFramework <ParentActorWithSupervisorStratery>(this, Props.Create(() => new ParentActorWithSupervisorStratery(parentSupervisorStrategy, childSupervisorStrategy)), 2); //act Action act = () => sut.ResolvedSupervisorStrategy(Guid.NewGuid().ToString()); //assert act.ShouldThrow <ActorNotFoundException>(); }
public void BackoffSupervisor_must_support_custom_supervision_strategy() { Action <IActorRef> assertCustomStrategy = supervisor => { supervisor.Tell(BackoffSupervisor.GetCurrentChild.Instance); var c1 = ExpectMsg <BackoffSupervisor.CurrentChild>().Ref; Watch(c1); c1.Tell("boom"); ExpectTerminated(c1); AwaitAssert(() => { supervisor.Tell(BackoffSupervisor.GetCurrentChild.Instance); // new instance ExpectMsg <BackoffSupervisor.CurrentChild>().Ref.Should().NotBeSameAs(c1); }); }; // TODO: use FilterException EventFilter.Exception <TestException>().Expect(2, () => { var stoppingStrategy = new OneForOneStrategy(ex => { if (ex is TestException) { return(Directive.Stop); } return(Directive.Escalate); }); var restartingStrategy = new OneForOneStrategy(ex => { if (ex is TestException) { return(Directive.Restart); } return(Directive.Escalate); }); assertCustomStrategy(Create(OnStopOptions().WithSupervisorStrategy(stoppingStrategy))); assertCustomStrategy(Create(OnFailureOptions().WithSupervisorStrategy(restartingStrategy))); }); }
public void Serialization_must_serialize_and_deserialize_DaemonMsgCreate_with_Deploy_and_RouterConfig() { var decider = Decider.From( Directive.Escalate); var supervisorStrategy = new OneForOneStrategy(3, TimeSpan.FromSeconds(10), decider); var deploy1 = new Deploy("path1", ConfigurationFactory.ParseString("a=1"), new RoundRobinPool(5, null, supervisorStrategy, null), new RemoteScope(new Address("akka", "Test", "host1", 1921)), "mydispatcher"); var deploy2 = new Deploy("path2", ConfigurationFactory.ParseString("a=2"), FromConfig.Instance, new RemoteScope(new Address("akka", "Test", "host2", 1922)), Deploy.NoDispatcherGiven); VerifySerialization(new DaemonMsgCreate(Props.Create <MyActor>().WithDispatcher("my-disp").WithDeploy(deploy1), deploy2, "foo", _supervisor)); }
public void UnitTestFramework_TheParentsSupervisorStrategyIsReturnedWhenTheChildDoesNotHaveOneSetInItsProps() { //arrange SupervisorStrategy parentSupervisorStrategy = new AllForOneStrategy(exception => Directive.Restart); SupervisorStrategy childSupervisorStrategy = new OneForOneStrategy(exception => Directive.Restart); UnitTestFramework <ParentActorWithSupervisorStratery> sut = UnitTestFrameworkSettings .Empty .CreateFramework <ParentActorWithSupervisorStratery>( this, Props.Create(() => new ParentActorWithSupervisorStratery(parentSupervisorStrategy, childSupervisorStrategy)), 2); //act SupervisorStrategy result = sut.ResolvedSupervisorStrategy("ChildWithChildSupervisorStrategy"); //assert result.Should().BeSameAs(childSupervisorStrategy); }
public void OneForOneStrategy_WhenRestartedMoreThanMaximumAllowedRetriesWithinSpecifiedTimePeriod_ShouldStopChild() { var childMailboxStats = new TestMailboxStatistics(msg => msg is Stopped); var strategy = new OneForOneStrategy((pid, reason) => SupervisorDirective.Restart, 3, TimeSpan.FromMilliseconds(100)); var childProps = Props.FromProducer(() => new ChildActor()) .WithMailbox(() => UnboundedMailbox.Create(childMailboxStats)); var parentProps = Props.FromProducer(() => new ParentActor(childProps)) .WithChildSupervisorStrategy(strategy); var parent = Context.Spawn(parentProps); Context.Send(parent, "1st restart"); Context.Send(parent, "2nd restart"); Context.Send(parent, "3rd restart"); Context.Send(parent, "4th restart"); childMailboxStats.Reset.Wait(1000); Assert.Contains(Stop.Instance, childMailboxStats.Posted); Assert.Contains(Stop.Instance, childMailboxStats.Received); }
public void CanSerializeSupervisor() { var decider = Decider.From( Directive.Restart, Directive.Stop.When<ArgumentException>(), Directive.Stop.When<NullReferenceException>()); var supervisor = new OneForOneStrategy(decider); var serializer = Sys.Serialization.FindSerializerFor(supervisor); var bytes = serializer.ToBinary(supervisor); var sref = (OneForOneStrategy)serializer.FromBinary(bytes, typeof(OneForOneStrategy)); Assert.NotNull(sref); var sdecider = sref.Decider as DeployableDecider; Assert.Equal(decider.Pairs[0], sdecider.Pairs[0]); Assert.Equal(decider.Pairs[1], sdecider.Pairs[1]); Assert.Equal(supervisor.MaxNumberOfRetries, sref.MaxNumberOfRetries); Assert.Equal(supervisor.WithinTimeRangeMilliseconds, sref.WithinTimeRangeMilliseconds); Assert.Equal(decider.DefaultDirective, sdecider.DefaultDirective); }
protected override SupervisorStrategy SupervisorStrategy() { var strategy = new OneForOneStrategy( exception => { if (exception is SimulatedCurruptStateException) { return(Directive.Restart); } if (exception is SimulatedTerribleMovieException) { return(Directive.Resume); } return(Directive.Restart); }); return(strategy); }
public void Cluster_aware_routers_must_use_provided_supervisor_strategy() { var escalator = new OneForOneStrategy( exception => { TestActor.Tell("supervised"); return(Directive.Stop); }); var settings = new ClusterRouterPoolSettings(1, 1, true); var router = Sys.ActorOf( new ClusterRouterPool(new RoundRobinPool(1, null, escalator, Dispatchers.DefaultDispatcherId), settings) .Props(Props.Create(() => new KillableActor(TestActor))), "therouter"); router.Tell("go away"); ExpectMsg("supervised"); }
public async Task RemoteRouter_must_set_supplied_SupervisorStrategy() { var probe = CreateTestProbe(masterSystem); var escalator = new OneForOneStrategy(ex => { probe.Ref.Tell(ex); return(Directive.Escalate); }); var router = masterSystem.ActorOf(new RemoteRouterConfig( new RoundRobinPool(1, null, escalator, Dispatchers.DefaultDispatcherId), new[] { new Address("akka.tcp", sysName, "127.0.0.1", port) }).Props(Props.Empty), "blub3"); router.Tell(new GetRoutees(), probe.Ref); // Need to be able to bind EventFilter to additional actor system (masterActorSystem in this case) before this code works // EventFilter.Exception<ActorKilledException>().ExpectOne(() => probe.ExpectMsg <Routees>(TimeSpan.FromSeconds(10)).Members.Head().Send(Kill.Instance, TestActor); //); probe.ExpectMsg <ActorKilledException>(TimeSpan.FromSeconds(10)); }
public void An_actor_Must_process_stashed_messages_after_restart() { SupervisorStrategy strategy = new OneForOneStrategy(2, TimeSpan.FromSeconds(1), e => Directive.Restart); var boss = ActorOf(() => new Supervisor(strategy)); var restartLatch = CreateTestLatch(); var hasMsgLatch = CreateTestLatch(); var slaveProps = Props.Create(() => new SlaveActor(restartLatch, hasMsgLatch, "stashme")); //Send the props to supervisor, which will create an actor and return the ActorRef var slave = boss.AskAndWait <ActorRef>(slaveProps, TestKitSettings.DefaultTimeout); //send a message that will be stashed slave.Tell("stashme"); //this will crash the slave. slave.Tell("crash"); //During preRestart restartLatch is opened //After that the cell will unstash "stashme", it should be received by the slave and open hasMsgLatch restartLatch.Ready(TimeSpan.FromSeconds(10)); hasMsgLatch.Ready(TimeSpan.FromSeconds(10)); }
public void BackoffSupervisorWithAutoResetWithSupervisorStrategy(ApplicationEnvironment applicationEnvironment) { ActorSystem actorSystem = ActorSystem.Create("app"); // This class represents a configuration object used in creating an // ActorBase actor Props childProps = Props.Create <EchoActor>(); // TimeSpan minBackoff = TimeSpan.FromSeconds(3); string childName = "myEcho"; TimeSpan maxBackoff = TimeSpan.FromSeconds(30); double randomFactor = 0.2; int maxNrOfRetries = 2; // Builds back-off options for creating a back-off supervisor. OneForOneStrategy supervisorStrategy = new OneForOneStrategy(exception => { TestUtilities.ConsoleWriteJson(new { Message = $"{GetType().Name} OneForOneStrategy", ExceptionMessage = exception.Message }); TestUtilities.ThreadSleepSeconds(10); if (exception is FileNotFoundException) { return(Directive.Restart); } return(Directive.Escalate); }); BackoffOptions backoffOptions = Backoff.OnStop(childProps, childName, minBackoff, maxBackoff, randomFactor, maxNrOfRetries).WithAutoReset(TimeSpan.FromSeconds(10)).WithSupervisorStrategy(supervisorStrategy); Props supervisor = BackoffSupervisor.Props(backoffOptions); IActorRef supervisorActor = actorSystem.ActorOf(supervisor, "echoSupervisor"); supervisorActor.Tell("EchoMessage1"); supervisorActor.Tell(new FileNotFoundException("File not found exception")); supervisorActor.Tell("EchoMessage2"); supervisorActor.Tell("EchoMessage3"); TestUtilities.MethodEnds(); }
public void Routers_in_general_must_default_to_all_for_one_always_escalate_strategy() { var restarter = new OneForOneStrategy(e => { TestActor.Tell(e); return(Directive.Restart); }); var supervisor = Sys.ActorOf(Props.Create(() => new Supervisor(restarter))); supervisor.Tell(new RoundRobinPool(3).Props(Props.Create(() => new RestartActor(TestActor)))); var router = ExpectMsg <IActorRef>(); EventFilter.Exception <ArgumentException>("die").ExpectOne(() => { router.Tell("die"); }); ExpectMsg <ArgumentException>().Message.Should().Be("die"); ExpectMsg("restarted"); ExpectMsg("restarted"); ExpectMsg("restarted"); }
public void A_supervisor_hierarchy_must_Restart_Manager_And_Workers_In_AllForOne() { var countDown = new CountdownEvent(4); SupervisorStrategy strategy = new OneForOneStrategy(_ => Directive.Restart); var boss = ActorOf(Props.Create(() => new Supervisor(strategy)), "boss"); Func <Exception, Directive> decider = _ => { return(Directive.Escalate); }; var managerProps = new PropsWithName(Props.Create(() => new CountDownActor(countDown, new AllForOneStrategy(decider))), "manager"); var manager = boss.Ask <IActorRef>(managerProps, TestKitSettings.DefaultTimeout).Result; var workerProps = Props.Create(() => new CountDownActor(countDown, SupervisorStrategy.DefaultStrategy)); var worker1 = manager.Ask <IActorRef>(new PropsWithName(workerProps, "worker1"), TestKitSettings.DefaultTimeout).Result; var worker2 = manager.Ask <IActorRef>(new PropsWithName(workerProps, "worker2"), TestKitSettings.DefaultTimeout).Result; var worker3 = manager.Ask <IActorRef>(new PropsWithName(workerProps, "worker3"), TestKitSettings.DefaultTimeout).Result; EventFilter.Exception <ActorKilledException>().ExpectOne(() => { worker1.Tell(Kill.Instance); // manager + all workers should be restarted by only killing a worker // manager doesn't trap exits, so boss will restart manager countDown.Wait(TimeSpan.FromSeconds(5)).ShouldBe(true); }); }
public void BackoffSupervisor_must_support_manual_reset() { Action <IActorRef> assertManualReset = supervisor => { supervisor.Tell(BackoffSupervisor.GetCurrentChild.Instance); var c1 = ExpectMsg <BackoffSupervisor.CurrentChild>().Ref; Watch(c1); c1.Tell("boom"); ExpectTerminated(c1); AwaitAssert(() => { supervisor.Tell(BackoffSupervisor.GetRestartCount.Instance); ExpectMsg <BackoffSupervisor.RestartCount>().Count.Should().Be(1); }); AwaitAssert(() => { supervisor.Tell(BackoffSupervisor.GetCurrentChild.Instance); // new instance ExpectMsg <BackoffSupervisor.CurrentChild>().Ref.Should().NotBeSameAs(c1); }); // TODO: this Thread.Sleep should be removed Thread.Sleep(500); supervisor.Tell("hello"); ExpectMsg("hello"); // making sure the Reset is handled by supervisor supervisor.Tell("hello"); ExpectMsg("hello"); supervisor.Tell(BackoffSupervisor.GetRestartCount.Instance); ExpectMsg <BackoffSupervisor.RestartCount>().Count.Should().Be(0); }; // TODO: use FilterException EventFilter.Exception <TestException>().Expect(2, () => { var stoppingStrategy = new OneForOneStrategy(ex => { if (ex is TestException) { return(Directive.Stop); } // TODO: should restart be there? return(Directive.Restart); }); var restartingStrategy = new OneForOneStrategy(ex => { if (ex is TestException) { return(Directive.Restart); } // TODO: should restart be there? return(Directive.Restart); }); assertManualReset( Create(OnStopOptions(ManualChild.Props(TestActor)) .WithManualReset() .WithSupervisorStrategy(stoppingStrategy))); assertManualReset( Create(OnFailureOptions(ManualChild.Props(TestActor)) .WithManualReset() .WithSupervisorStrategy(restartingStrategy))); }); }
public void A_constructed_AllForOne_supervisor_strategy_with_nullable_retries_and_a_decider_has_the_expected_properties(int?retries, int expectedRetries) { var uut = new OneForOneStrategy(retries, null, Decider.From(Directive.Restart)); Assert.Equal(uut.MaxNumberOfRetries, expectedRetries); }
public void A_constructed_AllForOne_supervisor_strategy_with_nullable_timeouts_and_a_decider_has_the_expected_properties(TimeSpan?timeout, int expectedTimeoutMilliseconds) { var uut = new OneForOneStrategy(-1, timeout, Decider.From(Directive.Restart)); Assert.Equal(uut.WithinTimeRangeMilliseconds, expectedTimeoutMilliseconds); }
public BackoffOptionsImpl(IBackoffType backoffType, Props childProps, string childName, TimeSpan minBackoff, TimeSpan maxBackoff, double randomFactor, IBackoffReset reset, OneForOneStrategy strategy) { _backoffType = backoffType ?? RestartImpliesFailure.Instance; _childProps = childProps; _childName = childName; _minBackoff = minBackoff; _maxBackoff = maxBackoff; _randomFactor = randomFactor; _reset = reset ?? new AutoReset(_minBackoff); _strategy = strategy; }
/// <summary> /// Returns a new <see cref="BackoffOptions"/> with the supervisorStrategy. /// </summary> /// <param name="supervisorStrategy">The <see cref="SupervisorStrategy"/> that the back-off supervisor will use. The default supervisor strategy is used as fallback if the specified SupervisorStrategy (its decider) does not explicitly handle an exception</param> public abstract BackoffOptions WithSupervisorStrategy(OneForOneStrategy supervisorStrategy);
public override BackoffOptions WithSupervisorStrategy(OneForOneStrategy supervisorStrategy) { return(new BackoffOptionsImpl(_backoffType, _childProps, _childName, _minBackoff, _maxBackoff, _randomFactor, _reset, supervisorStrategy, _replyWhileStopped, _finalStopMessage)); }
public BackoffOptionsImpl(IBackoffType backoffType, Props childProps, string childName, TimeSpan minBackoff, TimeSpan maxBackoff, double randomFactor, IBackoffReset reset, OneForOneStrategy strategy, object replyWhileStopped = null, Func <object, bool> finalStopMessage = null) { _backoffType = backoffType ?? RestartImpliesFailure.Instance; _childProps = childProps; _childName = childName; _minBackoff = minBackoff; _maxBackoff = maxBackoff; _randomFactor = randomFactor; _reset = reset ?? new AutoReset(_minBackoff); _strategy = strategy; _replyWhileStopped = replyWhileStopped; _finalStopMessage = finalStopMessage; }