public void TestSetup() { request = Request.Get("foo/bar"); replicas = Enumerable.Range(0, 10).Select(i => new Uri($"http://replica-{i}/")).ToArray(); resultSources = replicas.ToDictionary(r => r, _ => new TaskCompletionSource <ReplicaResult>()); parameters = RequestParameters.Empty.WithConnectionTimeout(1.Seconds()); sender = Substitute.For <IRequestSender>(); sender .SendToReplicaAsync(Arg.Any <Uri>(), Arg.Any <Request>(), Arg.Any <TimeSpan?>(), Arg.Any <TimeSpan>(), Arg.Any <CancellationToken>()) .Returns(info => resultSources[info.Arg <Uri>()].Task); delaySources = replicas.Select(_ => new TaskCompletionSource <bool>()).ToList(); delaySourcesEnumerator = delaySources.GetEnumerator(); delaysPlanner = Substitute.For <IForkingDelaysPlanner>(); SetupDelaysPlanner(); delaysProvider = Substitute.For <IForkingDelaysProvider>(); SetupForkingDelays(1.Milliseconds()); tokenSource = new CancellationTokenSource(); token = tokenSource.Token; strategy = new ForkingRequestStrategy(delaysProvider, delaysPlanner, 3); }
public void Should_cancel_remaining_requests_and_delays_when_receiving_accepted_result() { var tokens = new List <CancellationToken>(); sender .When(s => s.SendToReplicaAsync(Arg.Any <Uri>(), Arg.Any <Request>(), Arg.Any <TimeSpan?>(), Arg.Any <TimeSpan>(), Arg.Any <CancellationToken>())) .Do(info => tokens.Add(info.Arg <CancellationToken>())); delaysPlanner .When(p => p.Plan(Arg.Any <TimeSpan>(), Arg.Any <CancellationToken>())) .Do(info => tokens.Add(info.Arg <CancellationToken>())); strategy = new ForkingRequestStrategy(delaysProvider, delaysPlanner, int.MaxValue); var sendTask = strategy.SendAsync(request, parameters, sender, Budget.WithRemaining(5.Seconds()), replicas, replicas.Length, token); CompleteForkingDelay(); CompleteForkingDelay(); CompleteForkingDelay(); CompleteRequest(replicas.First(), ResponseVerdict.Accept); sendTask.GetAwaiter().GetResult(); tokens.Should().HaveCount(8); foreach (var t in tokens) { t.IsCancellationRequested.Should().BeTrue(); } }
public void Should_not_try_to_determine_forking_delay_when_parallelism_level_is_already_reached() { strategy = new ForkingRequestStrategy(delaysProvider, delaysPlanner, 1); strategy.SendAsync(request, parameters, sender, Budget.Infinite, replicas, replicas.Length, token); delaysProvider.ReceivedCalls().Should().BeEmpty(); }
public SimpleClusterClient(Uri[] addressList, TimeSpan?timeout = null, ILog log = null) { replicasCount = addressList.Length; globalTimeout = timeout ?? TimeSpan.FromSeconds(15); clusterClient = new ClusterClient(log, config => { config.ClusterProvider = new ConstantTopologyClusterProvider(addressList); config.SetupWebRequestTransport(); config.SetupWeighedReplicaOrdering(builder => { builder.AddAdaptiveHealthModifierWithLinearDecay(TuningPolicies.ByResponseVerdict, 10.Minutes()); }); }); forkingRequestStrategy = new ForkingRequestStrategy(new EqualDelaysProvider(addressList.Length), addressList.Length); parallelRequestStrategy = new ParallelRequestStrategy(addressList.Length); }
public void Should_launch_requests_except_last_with_connection_timeout() { sender.ClearReceivedCalls(); strategy = new ForkingRequestStrategy(delaysProvider, delaysPlanner, replicas.Length); strategy.SendAsync(request, parameters, sender, Budget.WithRemaining(5.Seconds()), replicas, replicas.Length, token); for (var i = 0; i < replicas.Length; ++i) { CompleteForkingDelay(); } for (var i = 0; i < replicas.Length - 1; ++i) { sender.Received(1).SendToReplicaAsync(replicas[i], request, parameters.ConnectionTimeout, Arg.Any <TimeSpan>(), Arg.Any <CancellationToken>()); } sender.Received(1).SendToReplicaAsync(replicas.Last(), request, null, Arg.Any <TimeSpan>(), Arg.Any <CancellationToken>()); }