public async Task Scatter_gather_router_must_return_response_even_if_one_of_the_actors_has_stopped() { var shutdownLatch = new TestLatch(1); var actor1 = Sys.ActorOf(Props.Create(() => new StopActor(1))); var actor2 = Sys.ActorOf(Props.Create(() => new StopActor(14))); var paths = new []{actor1,actor2}; var routedActor = Sys.ActorOf(new ScatterGatherFirstCompletedGroup(paths, TimeSpan.FromSeconds(3)).Props()); routedActor.Tell(new Broadcast(new Stop(1))); shutdownLatch.Open(); var res = await routedActor.Ask<int>(0, TimeSpan.FromSeconds(10)); res.ShouldBe(14); }
public void GracefulStop_must_complete_Task_with_TaskCanceledException_when_actor_not_terminated_within_timeout() { //arrange var target = Sys.ActorOf<TargetActor>(); var latch = new TestLatch(); //act target.Tell(Tuple.Create(latch, TimeSpan.FromSeconds(2))); //assert XAssert.Throws<TaskCanceledException>(() => { var task = target.GracefulStop(TimeSpan.FromMilliseconds(500)); task.Wait(); var result = task.Result; }); latch.Open(); }
public void Router_in_general_must_use_specified_resizer_when_resizer_not_configured() { var latch = new TestLatch(1); var resizer = new TestResizer(latch); var router = Sys.ActorOf( Props.Create<BlackHoleActor>() .WithRouter(new RoundRobinPool(0, resizer, SupervisorStrategy.DefaultStrategy, null))); latch.Open(); router.Tell(new GetRoutees(),TestActor); ExpectMsg<Routees>().Members.Count().ShouldBe(2); Sys.Stop(router); }
public void Router_in_general_must_not_terminate_when_resizer_is_used() { var latch = new TestLatch(1); var resizer = new TestResizer(latch); var router = Sys.ActorOf(new RoundRobinPool( 0, resizer,SupervisorStrategy.DefaultStrategy,null).Props(Props.Create<BlackHoleActor>())); Watch(router); latch.Open(); //Await.ready(latch, remainingOrDefault); //TODO: what is remainingOrDefault router.Tell(new GetRoutees(),TestActor); var routees = ExpectMsg<Routees>().Members.ToList(); routees.Count().ShouldBe(2); routees.ForEach(r => r.Send(PoisonPill.Instance,TestActor)); // expect no Terminated ExpectNoMsg(TimeSpan.FromSeconds(2)); }
public SlaveActor(TestLatch restartLatch, TestLatch hasMsgLatch, string expectedUnstashedMessage) { _restartLatch = restartLatch; Receive("crash", _ => { throw new Exception("Received \"crash\""); }); // when restartLatch is not yet open, stash all messages != "crash" Receive<object>(_ => !restartLatch.IsOpen, m => Stash.Stash()); // when restartLatch is open, must receive the unstashed message Receive(expectedUnstashedMessage, _ => hasMsgLatch.Open()); }
public void Conflate_must_restart_when_aggregate_throws_and_a_ResumingDecider_is_used() { var sourceProbe = this.CreatePublisherProbe<int>(); var sinkProbe = this.CreateManualSubscriberProbe<List<int>>(); var saw4Latch = new TestLatch(); var graph = Source.FromPublisher(sourceProbe).ConflateWithSeed(i => new List<int> { i }, (state, elem) => { if (elem == 2) throw new TestException("three is a four letter word"); if (elem == 4) saw4Latch.Open(); state.Add(elem); return state; }) .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider)) .To(Sink.FromSubscriber(sinkProbe)) .WithAttributes(Attributes.CreateInputBuffer(1, 1)); RunnableGraph.FromGraph(graph).Run(Materializer); var sub = sourceProbe.ExpectSubscription(); var sinkSub = sinkProbe.ExpectSubscription(); // push the first three values, the third will trigger // the exception sub.ExpectRequest(1); sub.SendNext(1); // causing the 1 to get thrown away sub.ExpectRequest(1); sub.SendNext(2); sub.ExpectRequest(1); sub.SendNext(3); sub.ExpectRequest(1); sub.SendNext(4); // and consume it, so that the next element // will trigger seed saw4Latch.Ready(TimeSpan.FromSeconds(3)); sinkSub.Request(1); sinkProbe.ExpectNext().ShouldAllBeEquivalentTo(new [] {1, 3, 4}); }
public void Conflate_must_restart_when_aggregate_throws_and_a_RestartingDecider_is_used() { var sourceProbe = this.CreatePublisherProbe<string>(); var sinkProbe = this.CreateSubscriberProbe<string>(); var latch = new TestLatch(); var conflate = Flow.Create<string>().ConflateWithSeed(i => i, (state, elem) => { if (elem == "two") { latch.Open(); throw new TestException("two is a three letter word"); } return state + elem; }).WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider)); var graph = Source.FromPublisher(sourceProbe) .Via(conflate) .To(Sink.FromSubscriber(sinkProbe)) .WithAttributes(Attributes.CreateInputBuffer(4, 4)); RunnableGraph.FromGraph(graph).Run(Materializer); var sub = sourceProbe.ExpectSubscription(); sub.ExpectRequest(4); sub.SendNext("one"); sub.SendNext("two"); sub.SendNext("three"); sub.SendComplete(); //"one" should be lost latch.Ready(TimeSpan.FromSeconds(3)); sinkProbe.RequestNext("three"); }
public void Conflate_must_restart_when_seed_throws_and_a_RestartDescider_is_used() { var sourceProbe = this.CreatePublisherProbe<int>(); var sinkProbe = this.CreateManualSubscriberProbe<int>(); var exceptionlath = new TestLatch(); var graph = Source.FromPublisher(sourceProbe).ConflateWithSeed(i => { if (i%2 == 0) { exceptionlath.Open(); throw new TestException("I hate even seed numbers"); } return i; }, (sum, i) => sum + i) .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider)) .To(Sink.FromSubscriber(sinkProbe)) .WithAttributes(Attributes.CreateInputBuffer(1, 1)); RunnableGraph.FromGraph(graph).Run(Materializer); var sub = sourceProbe.ExpectSubscription(); var sinkSub = sinkProbe.ExpectSubscription(); // push the first value sub.ExpectRequest(1); sub.SendNext(1); // and consume it, so that the next element // will trigger seed sinkSub.Request(1); sinkProbe.ExpectNext(1); sub.ExpectRequest(1); sub.SendNext(2); // make sure the seed exception happened // before going any further exceptionlath.Ready(TimeSpan.FromSeconds(3)); sub.ExpectRequest(1); sub.SendNext(3); // now we should have lost the 2 and the accumulated state sinkSub.Request(1); sinkProbe.ExpectNext(3); }