示例#1
0
        public void Can_serialize_RoundRobinPoolWithCustomResizer()
        {
            var defaultResizer = new DefaultResizer(2, 4, 1, 0.5, 0.2, 0.1, 55);
            var message        = new RoundRobinPool(nrOfInstances: 25, resizer: defaultResizer);

            AssertEqual(message);
        }
示例#2
0
        public void DefaultResizer_must_backoff()
        {
            Within(TimeSpan.FromSeconds(10), () =>
            {
                var resizer = new DefaultResizer(2, 5, pressureThreshold: 1, rampupRate: 1.0d, backoffRate: 1.0d,
                                                 messagesPerResize: 2, backoffThreshold: 0.4d);

                var router = Sys.ActorOf(Props.Create <BackoffActor>().WithRouter(new RoundRobinPool(0, resizer)));

                // put some pressure on the router
                for (var i = 0; i < 25; i++)
                {
                    router.Tell(150);
                    Thread.Sleep(20);
                }

                var z = RouteeSize(router);
                Assert.True(z > 2);
                Thread.Sleep(300);

                // let it cool down
                AwaitCondition(() =>
                {
                    router.Tell(0); //trigger resize
                    Thread.Sleep(20);
                    return(RouteeSize(router) < z);
                }, null, TimeSpan.FromMilliseconds(500));
            });
        }
示例#3
0
        public void DefaultResizer_must_use_settings_to_evaluate_rampup()
        {
            var resizer = new DefaultResizer(lower: 2, upper: 10, rampupRate: 0.2);

            resizer.Rampup(pressure: 9, capacity: 10).Should().Be(0);
            resizer.Rampup(pressure: 5, capacity: 5).Should().Be(1);
            resizer.Rampup(pressure: 6, capacity: 6).Should().Be(2);
        }
示例#4
0
        public void DefaultResizer_must_use_settings_to_evaluate_rampup()
        {
            // ReSharper disable once RedundantArgumentDefaultValue (exposing the values we're testing makes this test understandable.)
            var resizer = new DefaultResizer(2, 10, rampupRate: 0.2d);

            resizer.Rampup(9, 10).ShouldBe(0);
            resizer.Rampup(5, 5).ShouldBe(1);
            resizer.Rampup(6, 6).ShouldBe(2);
        }
示例#5
0
        public void Can_serialize_FromConfigWithResizerAndDispatcher()
        {
            var defaultResizer = new DefaultResizer(2, 4, 1, 0.5D, 0.3D, 0.1D, 55);
            var fromConfig     = FromConfig.Instance
                                 .WithResizer(defaultResizer)
                                 .WithDispatcher("my-own-dispatcher");

            AssertEqual(fromConfig);
        }
示例#6
0
        public void CanSerializeResizer()
        {
            var message      = new DefaultResizer(1, 20);
            var serializer   = Sys.Serialization.FindSerializerFor(message);
            var serialized   = serializer.ToBinary(message);
            var deserialized = (DefaultResizer)serializer.FromBinary(serialized, typeof(DefaultResizer));

            Assert.Equal(message, deserialized);
        }
示例#7
0
        public void Can_serialize_ConsistentHashingPoolWithDispatcherAndResizer()
        {
            var defaultResizer = new DefaultResizer(2, 4, 1, 0.5D, 0.3D, 0.1D, 55);
            var message        = new ConsistentHashingPool(
                nrOfInstances: 25,
                routerDispatcher: "my-dispatcher",
                usePoolDispatcher: true,
                resizer: defaultResizer,
                supervisorStrategy: SupervisorStrategy.DefaultStrategy);

            AssertEqual(message);
        }
示例#8
0
        public void DefaultResizer_must_use_settings_to_evaluate_backoff()
        {
            var resizer = new DefaultResizer(lower: 2, upper: 10, backoffThreshold: 0.3d, backoffRate: 0.1d);

            resizer.Backoff(pressure: 10, capacity: 10).Should().Be(0);
            resizer.Backoff(pressure: 4, capacity: 10).Should().Be(0);
            resizer.Backoff(pressure: 3, capacity: 10).Should().Be(0);
            resizer.Backoff(pressure: 2, capacity: 10).Should().Be(-1);
            resizer.Backoff(pressure: 0, capacity: 10).Should().Be(-1);
            resizer.Backoff(pressure: 1, capacity: 9).Should().Be(-1);
            resizer.Backoff(pressure: 0, capacity: 9).Should().Be(-1);
        }
示例#9
0
        public void Can_serialize_RoundRobinPoolWithCustomDispatcher()
        {
            var defaultResizer = new DefaultResizer(2, 4, 1, 0.5, 0.2, 0.1, 55);

            var message = new RoundRobinPool(
                nrOfInstances: 25,
                resizer: defaultResizer,
                supervisorStrategy: Pool.DefaultSupervisorStrategy,
                routerDispatcher: "my-dispatcher",
                usePoolDispatcher: true);

            AssertEqual(message);
        }
        //
        // DefaultResizer
        //
        private byte[] DefaultResizerToProto(DefaultResizer defaultResizer)
        {
            var message = new Proto.Msg.DefaultResizer();

            message.LowerBound        = (uint)defaultResizer.LowerBound;
            message.UpperBound        = (uint)defaultResizer.UpperBound;
            message.PressureThreshold = (uint)defaultResizer.PressureThreshold;
            message.RampupRate        = defaultResizer.RampupRate;
            message.BackoffThreshold  = defaultResizer.BackoffThreshold;
            message.BackoffRate       = defaultResizer.BackoffRate;
            message.MessagesPerResize = (uint)defaultResizer.MessagesPerResize;
            return(message.ToByteArray());
        }
示例#11
0
        public async Task DefaultResizer_with_ReceiveAsync_must_grow_as_needed_under_pressure()
        {
            var resizer = new DefaultResizer(
                lower: 3,
                upper: 5,
                rampupRate: 0.1,
                backoffRate: 0.0,
                pressureThreshold: 1,
                messagesPerResize: 1,
                backoffThreshold: 0.0);

            var router = Sys.ActorOf(new RoundRobinPool(0, resizer).Props(Props.Create <PressureAsyncActor>()));

            // first message should create the minimum number of routees
            router.Tell("echo");
            ExpectMsg("reply");

            RouteeSize(router).Should().Be(resizer.LowerBound);

            Func <int, TimeSpan, Task> loop = async(loops, d) =>
            {
                for (var i = 0; i < loops; i++)
                {
                    router.Tell(d);

                    //sending too quickly will result in skipped resize due to many ResizeInProgress conflicts
                    await Task.Delay(Dilated(20.Milliseconds()));
                }

                var max = d.TotalMilliseconds * loops / resizer.LowerBound + Dilated(2.Seconds()).TotalMilliseconds;
                Within(TimeSpan.FromMilliseconds(max), () =>
                {
                    for (var i = 0; i < loops; i++)
                    {
                        ExpectMsg("done");
                    }
                });
            };

            // 2 more should go through without triggering more
            await loop(2, 200.Milliseconds());

            RouteeSize(router).Should().Be(resizer.LowerBound);

            // a whole bunch should max it out
            await loop(20, 500.Milliseconds());

            RouteeSize(router).Should().Be(resizer.UpperBound);
        }
示例#12
0
        public void DefaultResizer_must_use_settings_to_evaluate_backoff()
        {
            // ReSharper disable RedundantArgumentDefaultValue (exposing the values we're testing makes this test understandable.)
            var resizer = new DefaultResizer(2, 10, backoffThreshold: 0.3d, backoffRate: 0.1d);

            // ReSharper restore RedundantArgumentDefaultValue

            resizer.Backoff(10, 10).ShouldBe(0);
            resizer.Backoff(4, 10).ShouldBe(0);
            resizer.Backoff(3, 10).ShouldBe(0);
            resizer.Backoff(2, 10).ShouldBe(-1);
            resizer.Backoff(0, 10).ShouldBe(-1);
            resizer.Backoff(1, 9).ShouldBe(-1);
            resizer.Backoff(0, 9).ShouldBe(-1);
        }
示例#13
0
        public void DefaultResizer_must_be_possible_to_define_programmatically()
        {
            var latch   = new TestLatch(3);
            var resizer = new DefaultResizer(2, 3);
            var router  = Sys.ActorOf(Props.Create <ResizerTestActor>().WithRouter(new RoundRobinPool(0, resizer)));

            router.Tell(latch);
            router.Tell(latch);
            router.Tell(latch);

            latch.Ready(TestKitSettings.DefaultTimeout);

            //messagesPerResize is 10 so there is no risk of additional resize
            (RouteeSize(router)).ShouldBe(2);
        }
示例#14
0
        public void DefaultResizer_must_grow_as_needed_under_pressure()
        {
            var resizer = new DefaultResizer(3, 5, pressureThreshold: 1, rampupRate: 0.1d, backoffRate: 0.0d,
                                             messagesPerResize: 1, backoffThreshold: 0.0d);

            var router = Sys.ActorOf(Props.Create <PressureActor>().WithRouter(new RoundRobinPool(0, resizer)));

            //first message should create the minimum number of routees
            router.Tell("echo", TestActor);
            ExpectMsg("reply");

            (RouteeSize(router)).ShouldBe(resizer.LowerBound);

            Action <int, TimeSpan, int?> loop = (loops, span, expectedBound) =>
            {
                for (var i = 0; i < loops; i++)
                {
                    router.Tell(span, TestActor);
                    if (expectedBound.HasValue && RouteeSize(router) >= expectedBound.Value)
                    {
                        return;
                    }

                    //sending too quickly will result in skipped resize due to many resizeInProgress conflicts
                    Thread.Sleep(TimeSpan.FromMilliseconds(20));
                }

                var max = TimeSpan.FromMilliseconds((span.TotalMilliseconds * loops) / resizer.LowerBound) +
                          TimeSpan.FromSeconds(2);

                Within(max, () =>
                {
                    for (var i = 0; i < loops; i++)
                    {
                        ExpectMsg("done");
                    }
                    return(true);
                });
            };

            // 2 more should go through without triggering more
            loop(2, TimeSpan.FromMilliseconds(200), null);
            RouteeSize(router).ShouldBe(resizer.LowerBound);

            // a whole bunch should max it out
            loop(100, TimeSpan.FromMilliseconds(500), resizer.UpperBound);
            RouteeSize(router).ShouldBe(resizer.UpperBound);
        }
示例#15
0
        public void DefaultResizer_must_be_possible_to_define_programmatically()
        {
            var latch   = new TestLatch(3);
            var resizer = new DefaultResizer(lower: 2, upper: 3);

            var router = Sys.ActorOf(new RoundRobinPool(0, resizer).Props(Props.Create <ResizerTestActor>()));

            router.Tell(latch);
            router.Tell(latch);
            router.Tell(latch);

            latch.Ready(RemainingOrDefault);

            // MessagesPerResize is 10 so there is no risk of additional resize
            RouteeSize(router).Should().Be(2);
        }
示例#16
0
        public void DefaultResizer_must_use_settings_to_evaluate_capacity()
        {
            var resizer = new DefaultResizer(2, 3);
            var c1      = resizer.Capacity(new Routee[] { });

            c1.ShouldBe(2);

            var current = new Routee[]
            {
                new ActorRefRoutee(Sys.ActorOf <ResizerTestActor>()),
                new ActorRefRoutee(Sys.ActorOf <ResizerTestActor>())
            };
            var c2 = resizer.Capacity(current);

            c2.ShouldBe(0);
        }
示例#17
0
        public void DefaultResizer_must_use_settings_to_evaluate_capacity()
        {
            var resizer = new DefaultResizer(lower: 2, upper: 3);
            var c1      = resizer.Capacity(Enumerable.Empty <Routee>());

            c1.Should().Be(2);

            var current = new Routee[]
            {
                new ActorRefRoutee(Sys.ActorOf <ResizerTestActor>()),
                new ActorRefRoutee(Sys.ActorOf <ResizerTestActor>())
            };

            var c2 = resizer.Capacity(current);

            c2.Should().Be(0);
        }
示例#18
0
        public static IActorRef CreateCoordinator(ActorSystem actorSystem)
        {
            var defaultResizer = new DefaultResizer(
                lower: PoolRouterHelper.Lower,
                upper: PoolRouterHelper.Upper,
                pressureThreshold: 1,
                rampupRate: 0.2,
                backoffThreshold: 0.2,
                backoffRate: 0.1,
                messagesPerResize: PoolRouterHelper.MessagesPerResize);

            var pool = new RoundRobinPool(
                nrOfInstances: PoolRouterHelper.NrOfInstances,
                resizer: defaultResizer);

            return(actorSystem.ActorOf(
                       Props.Create(() => new CoordinatorArtespActor())
                       .WithRouter(pool), ActorsPath.CoordinatorArtespActor.Name));
        }
示例#19
0
        private IActorRef RouterFactory(string routerStrategy, BlockingCollection <string> queue)
        {
            var       resizer = new DefaultResizer(lower: 4, upper: 8, pressureThreshold: 1, rampupRate: 0.2, backoffThreshold: 0.3, backoffRate: 0.1, messagesPerResize: 1000);
            IActorRef routerActor;

            switch (routerStrategy.ToLower())
            {
            case "consistenthashing":
                routerActor = Context.System.ActorOf(KilometrePipeline.Prop(queue).WithRouter(new ConsistentHashingPool(4).WithResizer(resizer)), "ConsistentHashing");
                break;

            case "smallestmailbox":
                routerActor = Context.System.ActorOf(KilometrePipeline.Prop(queue).WithRouter(new SmallestMailboxPool(4).WithResizer(resizer)), "SmallestMailbox");
                break;

            default:
                routerActor = Context.System.ActorOf(KilometrePipeline.Prop(queue).WithRouter(new RoundRobinPool(4).WithResizer(resizer)), "RoundRobin");
                break;
            }
            //var t = Context.System.ActorOf(Props..Create<KilometrePipeline>().WithRouter(new ConsistentHashingPool(4).WithResizer(resizer)), "ConsistentHashing");
            return(routerActor);
        }
示例#20
0
        public void DefaultResizer_must_backoff()
        {
            Within(10.Seconds(), () =>
            {
                var resizer = new DefaultResizer(
                    lower: 2,
                    upper: 5,
                    rampupRate: 1.0d,
                    backoffRate: 1.0d,
                    backoffThreshold: 0.40d,
                    pressureThreshold: 1,
                    messagesPerResize: 2);

                var router = Sys.ActorOf(new RoundRobinPool(nrOfInstances: 0, resizer: resizer)
                                         .Props(Props.Create(() => new BackoffActor(Dilated))));

                // put some pressure on the router
                for (var i = 0; i < 15; i++)
                {
                    router.Tell(150);

                    Thread.Sleep(Dilated(20.Milliseconds()));
                }

                var z = RouteeSize(router);
                z.Should().BeGreaterThan(2);

                Thread.Sleep(Dilated(300.Milliseconds()));

                // let it cool down
                AwaitCondition(() =>
                {
                    router.Tell(0); //trigger resize
                    Thread.Sleep(Dilated(20.Milliseconds()));
                    return(RouteeSize(router) < z);
                }, Dilated(500.Milliseconds()));
            });
        }
示例#21
0
        public void Can_serialize_DefaultResizer()
        {
            var defaultResizer = new DefaultResizer(2, 4, 1, 0.5D, 0.3D, 0.1D, 55);

            AssertEqual(defaultResizer);
        }
        public void CanSerializeResizer()
        {
            var message = new DefaultResizer(1, 20);

            AssertEqual(message);
        }