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); }
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)); }); }
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); }
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); }
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); }
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); }
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); }
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); }
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()); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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)); }
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); }
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())); }); }
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); }