예제 #1
0
        public void Set_of_connected_cluster_systems_must_when_two_nodes_after_cluster_convergence_updates_membership_table_then_all_MembershipChangeListeners_should_be_triggered()
        {
            AwaitClusterUp(_config.First);

            RunOn(() =>
            {
                var latch             = new TestLatch();
                var expectedAddresses = ImmutableList.Create(GetAddress(_config.First), GetAddress(_config.Second));
                var listener          = Sys.ActorOf(Props.Create(() => new Listener(latch, expectedAddresses)).WithDeploy(Deploy.Local));
                Cluster.Subscribe(listener, new[] { typeof(ClusterEvent.IMemberEvent) });
                EnterBarrier("listener-1-registered");
                Cluster.Join(GetAddress(_config.First));
                latch.Ready();
            }, _config.First, _config.Second);

            RunOn(() =>
            {
                EnterBarrier("listener-1-registered");
            }, _config.Third);

            EnterBarrier("after-1");
        }
예제 #2
0
        public void A_FlattenMerge_must_cancel_substreams_when_failing_map_function()
        {
            var settings     = ActorMaterializerSettings.Create(Sys).WithSyncProcessingLimit(1).WithInputBuffer(1, 1);
            var materializer = ActorMaterializer.Create(Sys, settings);
            var p            = this.CreatePublisherProbe <int>();
            var ex           = new TestException("buh");
            var latch        = new TestLatch();

            Source.From(Enumerable.Range(1, 3)).MergeMany(10, i =>
            {
                if (i == 1)
                {
                    return(Source.FromPublisher(p));
                }

                latch.Ready(TimeSpan.FromSeconds(3));
                throw ex;
            }).RunWith(Sink.First <int>(), materializer);
            p.ExpectRequest();
            latch.CountDown();
            p.ExpectCancellation();
        }
예제 #3
0
        public async Task Random_group_must_deliver_messages_in_a_random_fashion()
        {
            const int connectionCount = 10;
            const int iterationCount  = 100;
            var       doneLatch       = new TestLatch(connectionCount);

            var replies = new Dictionary <string, int>();

            for (int i = 1; i <= connectionCount; i++)
            {
                replies["target-" + i] = 0;
            }

            var paths = Enumerable.Range(1, connectionCount).Select(n =>
            {
                var routee = Sys.ActorOf(Props.Create(() => new RandomGroupActor(doneLatch)), "target-" + n);
                return(routee.Path.ToStringWithoutAddress());
            });

            var actor = Sys.ActorOf(new RandomGroup(paths).Props(), "random-group1");

            for (int i = 0; i < iterationCount; i++)
            {
                for (int k = 0; k < connectionCount; k++)
                {
                    string id = await actor.Ask <string>("hit");

                    replies[id] = replies[id] + 1;
                }
            }

            actor.Tell(new Broadcast("end"));
            doneLatch.Ready(5.Seconds());

            replies.Values.ForEach(c => c.Should().BeGreaterThan(0));
            replies.Values.Any(c => c != iterationCount).ShouldBeTrue();
            replies.Values.Sum().Should().Be(iterationCount * connectionCount);
        }
예제 #4
0
        public void BroadcastGroup_router_must_broadcast_message_using_Ask()
        {
            var doneLatch = new TestLatch(2);

            var counter1 = new AtomicCounter(0);
            var actor1   = Sys.ActorOf(Props.Create(() => new BroadcastTarget(doneLatch, counter1)));

            var counter2 = new AtomicCounter(0);
            var actor2   = Sys.ActorOf(Props.Create(() => new BroadcastTarget(doneLatch, counter2)));

            var paths = new List <string> {
                actor1.Path.ToString(), actor2.Path.ToString()
            };
            var routedActor = Sys.ActorOf(new BroadcastGroup(paths).Props());

            routedActor.Ask(new Broadcast(1));
            routedActor.Tell(new Broadcast("end"));

            doneLatch.Ready(RemainingOrDefault);

            counter1.Current.Should().Be(1);
            counter2.Current.Should().Be(1);
        }
예제 #5
0
        public void Tail_chopping_group_router_must_deliver_a_broadcast_message_using_tell()
        {
            var doneLatch = new TestLatch(2);

            var counter1 = new AtomicCounter(0);
            var actor1   = Sys.ActorOf(Props.Create(() => new BroadcastTarget(doneLatch, counter1)));

            var counter2 = new AtomicCounter(0);
            var actor2   = Sys.ActorOf(Props.Create(() => new BroadcastTarget(doneLatch, counter2)));

            var paths = new List <string> {
                actor1.Path.ToString(), actor2.Path.ToString()
            };
            var routedActor = Sys.ActorOf(new TailChoppingGroup(paths, TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(100)).Props());

            routedActor.Tell(new Broadcast(1));
            routedActor.Tell(new Broadcast("end"));

            doneLatch.Ready(TestKitSettings.DefaultTimeout);

            counter1.Current.Should().Be(1);
            counter2.Current.Should().Be(1);
        }
예제 #6
0
        public async Task Random_pool_must_deliver_messages_in_a_random_fashion()
        {
            const int connectionCount = 10;
            const int iterationCount  = 100;
            var       doneLatch       = new TestLatch(connectionCount);

            var counter = new AtomicCounter(0);
            var replies = new Dictionary <int, int>();

            for (int i = 0; i < connectionCount; i++)
            {
                replies[i] = 0;
            }

            var actor = Sys.ActorOf(new RandomPool(connectionCount)
                                    .Props(Props.Create(() => new RandomActor(doneLatch, counter))), "random");

            for (int i = 0; i < iterationCount; i++)
            {
                for (int k = 0; k < connectionCount; k++)
                {
                    int id = await actor.Ask <int>("hit");

                    replies[id] = replies[id] + 1;
                }
            }

            counter.Current.ShouldBe(connectionCount);

            actor.Tell(new Broadcast("end"));
            doneLatch.Ready(TimeSpan.FromSeconds(5));

            replies.Values.ForEach(c => c.Should().BeGreaterThan(0));
            replies.Values.Any(c => c != iterationCount).ShouldBeTrue();
            replies.Values.Sum().Should().Be(iterationCount * connectionCount);
        }
예제 #7
0
        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");
        }
예제 #8
0
        public void FSMActor_must_unlock_the_lock()
        {
            var latches          = new Latches(Sys);
            var timeout          = 2.Seconds();
            var lockFsm          = Sys.ActorOf(Props.Create(() => new Lock("33221", 1.Seconds(), latches)));
            var transitionTester = Sys.ActorOf(Props.Create(() => new TransitionTester(latches)));

            lockFsm.Tell(new SubscribeTransitionCallBack(transitionTester));
            latches.InitialStateLatch.Ready(timeout);

            lockFsm.Tell('3');
            lockFsm.Tell('3');
            lockFsm.Tell('2');
            lockFsm.Tell('2');
            lockFsm.Tell('1');

            latches.UnlockedLatch.Ready(timeout);
            latches.TransitionLatch.Ready(timeout);
            latches.TransitionCallBackLatch.Ready(timeout);
            latches.LockedLatch.Ready(timeout);

            EventFilter.Warning("unhandled event").ExpectOne(() =>
            {
                lockFsm.Tell("not_handled");
                latches.UnhandledLatch.Ready(timeout);
            });

            var answerLatch = new TestLatch();
            var tester      = Sys.ActorOf(Props.Create(() => new AnswerTester(answerLatch, lockFsm)));

            tester.Tell(Hello.Instance);
            answerLatch.Ready(timeout);

            tester.Tell(Bye.Instance);
            latches.TerminatedLatch.Ready(timeout);
        }
예제 #9
0
        public void Random_must_be_able_to_shut_down_its_instance()
        {
            const int routeeCount = 7;
            var       testLatch   = new TestLatch(routeeCount);
            var       router      = Sys.ActorOf(new RandomPool(routeeCount).Props(Props.Create(() => new HelloWorldActor(testLatch))));

            router.Tell("hello", TestActor);
            router.Tell("hello", TestActor);
            router.Tell("hello", TestActor);
            router.Tell("hello", TestActor);
            router.Tell("hello", TestActor);

            Within(TimeSpan.FromSeconds(2), () => {
                ExpectMsg("world");
                ExpectMsg("world");
                ExpectMsg("world");
                ExpectMsg("world");
                ExpectMsg("world");
                return(true);
            });

            Sys.Stop(router);
            testLatch.Ready(TimeSpan.FromSeconds(5));
        }
예제 #10
0
        public void A_ForeachParallel_must_resume_after_function_failure()
        {
            this.AssertAllStagesStopped(() =>
            {
                var probe = CreateTestProbe();
                var latch = new TestLatch(1);

                var p = Source.From(Enumerable.Range(1, 5)).RunWith(Sink.ForEachParallel <int>(4, n =>
                {
                    if (n == 3)
                    {
                        throw new TestException("err1");
                    }

                    probe.Ref.Tell(n);
                    latch.Ready(TimeSpan.FromSeconds(10));
                }).WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider)), Materializer);

                latch.CountDown();
                probe.ExpectMsgAllOf(1, 2, 4, 5);

                p.Wait(TimeSpan.FromSeconds(5)).Should().BeTrue();
            }, Materializer);
        }
예제 #11
0
        public void Random_pool_must_be_able_to_shut_down_its_instance()
        {
            const int routeeCount = 7;
            var       testLatch   = new TestLatch(routeeCount);

            var actor = Sys.ActorOf(new RandomPool(routeeCount)
                                    .Props(Props.Create(() => new HelloWorldActor(testLatch))), "random-shutdown");

            actor.Tell("hello");
            actor.Tell("hello");
            actor.Tell("hello");
            actor.Tell("hello");
            actor.Tell("hello");

            Within(TimeSpan.FromSeconds(2), () => {
                for (int i = 1; i <= 5; i++)
                {
                    ExpectMsg("world");
                }
            });

            Sys.Stop(actor);
            testLatch.Ready(5.Seconds());
        }
예제 #12
0
        public void A_Flow_with_SelectAsyncUnordered_must_signal_task_failure()
        {
            this.AssertAllStagesStopped(() =>
            {
                var latch = new TestLatch(1);
                var c     = TestSubscriber.CreateManualProbe <int>(this);
                Source.From(Enumerable.Range(1, 5))
                .SelectAsyncUnordered(4, n => Task.Run(() =>
                {
                    if (n == 3)
                    {
                        throw new TestException("err1");
                    }

                    latch.Ready(TimeSpan.FromSeconds(10));
                    return(n);
                }))
                .To(Sink.FromSubscriber(c)).Run(Materializer);
                var sub = c.ExpectSubscription();
                sub.Request(10);
                c.ExpectError().InnerException.Message.Should().Be("err1");
                latch.CountDown();
            }, Materializer);
        }
예제 #13
0
        public void Registered_MembershipChangeListener_must_be_notified_when_new_node_is_exiting()
        {
            AwaitClusterUp(_config.First, _config.Second, _config.Third);

            RunOn(() =>
            {
                EnterBarrier("registered-listener");
                Cluster.Leave(GetAddress(_config.Second));
            }, _config.First);

            RunOn(() =>
            {
                var exitingLatch  = new TestLatch();
                var removedLatch  = new TestLatch();
                var secondAddress = GetAddress(_config.Second);
                var watcher       = Sys.ActorOf(Props.Create(() => new Watcher(exitingLatch, removedLatch, secondAddress))
                                                .WithDeploy(Deploy.Local));
                Cluster.Subscribe(watcher, new[] { typeof(ClusterEvent.IMemberEvent) });
                EnterBarrier("registered-listener");
                exitingLatch.Ready();
                removedLatch.Ready();
            }, _config.Second);

            RunOn(() =>
            {
                var exitingLatch  = new TestLatch();
                var secondAddress = GetAddress(_config.Second);
                var watcher       = Sys.ActorOf(Props.Create(() => new Watcher(exitingLatch, null, secondAddress))
                                                .WithDeploy(Deploy.Local));
                Cluster.Subscribe(watcher, new[] { typeof(ClusterEvent.IMemberEvent) });
                EnterBarrier("registered-listener");
                exitingLatch.Ready();
            }, _config.Third);

            EnterBarrier("finished");
        }
예제 #14
0
 public void Wait()
 {
     _waitForEvents?.Ready();
     _waitForEvents = null;
     _waitingToStart.Release();
 }
예제 #15
0
 public override void Schedule(Action run)
 {
     Task.Run(run);
     _latch.Ready(TimeSpan.FromSeconds(1));
 }
 public void Wait()
 {
     _waitForChildren?.Ready();
     _waitForChildren = null;
     _waitingToStart.Set();
 }
예제 #17
0
 protected override void PostStop()
 {
     _latch.Ready(3.Seconds());
 }
예제 #18
0
 protected override void ExecuteTask(IRunnable run)
 {
     run.Run();
     _latch.Ready(TimeSpan.FromSeconds(1));
 }
예제 #19
0
        public void An_actor_watching_a_remote_actor_in_the_cluster_must_receive_terminated_when_watched_node_becomes_down_removed()
        {
            Within(TimeSpan.FromSeconds(30), () =>
            {
                AwaitClusterUp(_config.First, _config.Second, _config.Third, _config.Fourth);
                EnterBarrier("cluster-up");

                RunOn(() =>
                {
                    EnterBarrier("subjected-started");

                    var path2            = new RootActorPath(GetAddress(_config.Second)) / "user" / "subject";
                    var path3            = new RootActorPath(GetAddress(_config.Third)) / "user" / "subject";
                    var watchEstablished = new TestLatch(2);
                    Sys.ActorOf(Props.Create(() => new Observer(path2, path3, watchEstablished, TestActor))
                                .WithDeploy(Deploy.Local), "observer1");

                    watchEstablished.Ready();
                    EnterBarrier("watch-established");
                    ExpectMsg(path2);
                    ExpectNoMsg(TimeSpan.FromSeconds(2));
                    EnterBarrier("second-terminated");
                    MarkNodeAsUnavailable(GetAddress(_config.Third));
                    AwaitAssert(() => Assert.True(ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Third))));
                    Cluster.Down(GetAddress(_config.Third));
                    //removed
                    AwaitAssert(() => Assert.False(ClusterView.Members.Select(x => x.Address).Contains(GetAddress(_config.Third))));
                    AwaitAssert(() => Assert.False(ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Third))));
                    ExpectMsg(path3);
                    EnterBarrier("third-terminated");
                }, _config.First);

                RunOn(() =>
                {
                    Sys.ActorOf(BlackHoleActor.Props, "subject");
                    EnterBarrier("subjected-started");
                    EnterBarrier("watch-established");
                    RunOn(() =>
                    {
                        MarkNodeAsUnavailable(GetAddress(_config.Second));
                        AwaitAssert(() => Assert.True(ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Second))));
                        Cluster.Down(GetAddress(_config.Second));
                        //removed
                        AwaitAssert(() => Assert.False(ClusterView.Members.Select(x => x.Address).Contains(GetAddress(_config.Second))));
                        AwaitAssert(() => Assert.False(ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Second))));
                    }, _config.Third);
                    EnterBarrier("second-terminated");
                    EnterBarrier("third-terminated");
                }, _config.Second, _config.Third, _config.Fourth);

                RunOn(() =>
                {
                    EnterBarrier("subjected-started");
                    EnterBarrier("watch-established");
                    EnterBarrier("second-terminated");
                    EnterBarrier("third-terminated");
                }, _config.Fifth);

                EnterBarrier("after-1");
            });
        }