/// <inheritdoc />
        public async Task SendAsync(Request request, RequestParameters parameters, IRequestSender sender, IRequestTimeBudget budget, IEnumerable <Uri> replicas, int replicasCount, CancellationToken cancellationToken)
        {
            var currentReplicaIndex = 0;

            foreach (var replica in replicas)
            {
                if (budget.HasExpired)
                {
                    break;
                }

                if (request.ContainsAlreadyUsedStream())
                {
                    break;
                }

                var timeout = TimeSpanArithmetics.Min(timeoutsProvider.GetTimeout(request, budget, currentReplicaIndex++, replicasCount), budget.Remaining);

                var connectionAttemptTimeout = currentReplicaIndex == replicasCount ? null : parameters.ConnectionTimeout;

                var result = await sender.SendToReplicaAsync(replica, request, connectionAttemptTimeout, timeout, cancellationToken).ConfigureAwait(false);

                if (result.Verdict == ResponseVerdict.Accept)
                {
                    break;
                }

                cancellationToken.ThrowIfCancellationRequested();
            }
        }
        public void TestSetup()
        {
            replica1 = new Uri("http://replica1/");
            replica2 = new Uri("http://replica2/");
            replica3 = new Uri("http://replica3/");
            replicas = new[] { replica1, replica2, replica3 };

            request    = Request.Get("/foo");
            parameters = RequestParameters.Empty.WithConnectionTimeout(1.Seconds());

            timeoutsProvider = Substitute.For <ISequentialTimeoutsProvider>();
            timeoutsProvider.GetTimeout(null, null, 0, 0).ReturnsForAnyArgs(1.Seconds(), 2.Seconds(), 3.Seconds());

            sender = Substitute.For <IRequestSender>();
            SetupResult(replica1, ResponseVerdict.Reject);
            SetupResult(replica2, ResponseVerdict.Reject);
            SetupResult(replica3, ResponseVerdict.Reject);

            tokenSource = new CancellationTokenSource();
            token       = tokenSource.Token;

            strategy = new SequentialRequestStrategy(timeoutsProvider);
        }
        public async Task SendAsync(Request request, IRequestSender sender, IRequestTimeBudget budget, IEnumerable <Uri> replicas, int replicasCount, CancellationToken cancellationToken)
        {
            var currentReplicaIndex = 0;

            foreach (var replica in replicas)
            {
                if (budget.HasExpired)
                {
                    break;
                }

                var timeout = TimeSpanExtensions.Min(timeoutsProvider.GetTimeout(request, budget, currentReplicaIndex++, replicasCount), budget.Remaining);

                var result = await sender.SendToReplicaAsync(replica, request, timeout, cancellationToken).ConfigureAwait(false);

                if (result.Verdict == ResponseVerdict.Accept)
                {
                    break;
                }

                cancellationToken.ThrowIfCancellationRequested();
            }
        }
        public void SetUp()
        {
            replica1 = new Uri("http://replica1/");
            replica2 = new Uri("http://replica2/");
            replica3 = new Uri("http://replica3/");
            replicas = new[] { replica1, replica2, replica3 };

            request = Request.Get("/foo");

            timeoutsProvider = Substitute.For <ISequentialTimeoutsProvider>();
            // ReSharper disable AssignNullToNotNullAttribute
            timeoutsProvider.GetTimeout(null, null, 0, 0).ReturnsForAnyArgs(1.Seconds(), 2.Seconds(), 3.Seconds());
            // ReSharper restore AssignNullToNotNullAttribute

            sender = Substitute.For <IRequestSender>();
            SetupResult(replica1, ResponseVerdict.Reject);
            SetupResult(replica2, ResponseVerdict.Reject);
            SetupResult(replica3, ResponseVerdict.Reject);

            token = new CancellationTokenSource().Token;

            strategy = new SequentialRequestStrategy(timeoutsProvider);
        }