예제 #1
0
        public void Should_not_retry_if_retry_policy_forbids_it()
        {
            retryPolicy.NeedToRetry(Arg.Any <Request>(), Arg.Any <RequestParameters>(), Arg.Any <IList <ReplicaResult> >()).Returns(false);

            Execute().Should().BeSameAs(result);

            nextModuleCalls.Should().Be(1);
        }
        public async Task <ClusterResult> ExecuteAsync(IRequestContext context, Func <IRequestContext, Task <ClusterResult> > next)
        {
            var attemptsUsed = 0;

            while (true)
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                var result = await next(context).ConfigureAwait(false);

                if (result.Status != ClusterResultStatus.ReplicasExhausted &&
                    result.Status != ClusterResultStatus.ReplicasNotFound)
                {
                    return(result);
                }

                if (context.Budget.HasExpired)
                {
                    return(result);
                }

                if (context.Request.ContainsAlreadyUsedStream())
                {
                    return(result);
                }

                if (++attemptsUsed >= retryStrategy.AttemptsCount)
                {
                    return(result);
                }

                if (!retryPolicy.NeedToRetry(context.Request, context.Parameters, result.ReplicaResults))
                {
                    return(result);
                }

                var retryDelay = retryStrategy.GetRetryDelay(attemptsUsed);
                if (retryDelay >= context.Budget.Remaining)
                {
                    return(result);
                }

                context.Log.Info("Could not obtain an acceptable response from cluster. Will retry after {RetryDelay}. Attempts used: {AttemptsUsed}/{AttemptsCount}.", retryDelay.ToPrettyString(), attemptsUsed, retryStrategy.AttemptsCount);

                if (retryDelay > TimeSpan.Zero)
                {
                    await Task.Delay(retryDelay, context.CancellationToken).ConfigureAwait(false);
                }

                (context as RequestContext)?.ResetReplicaResults();
            }
        }
예제 #3
0
        public async Task <ClusterResult> ExecuteAsync(IRequestContext context, Func <IRequestContext, Task <ClusterResult> > next)
        {
            var attemptsUsed = 0;

            while (true)
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                var result = await next(context).ConfigureAwait(false);

                if (result.Status != ClusterResultStatus.ReplicasExhausted)
                {
                    return(result);
                }

                if (context.Budget.HasExpired)
                {
                    return(result);
                }

                if (++attemptsUsed >= retryStrategy.AttemptsCount)
                {
                    return(result);
                }

                if (!retryPolicy.NeedToRetry(result.ReplicaResults))
                {
                    return(result);
                }

                var retryDelay = retryStrategy.GetRetryDelay(attemptsUsed);
                if (retryDelay >= context.Budget.Remaining)
                {
                    return(result);
                }

                context.Log.Info($"All replicas exhausted. Will retry after {retryDelay.ToPrettyString()}. Attempts used: {attemptsUsed}/{retryStrategy.AttemptsCount}.");

                if (retryDelay > TimeSpan.Zero)
                {
                    await Task.Delay(retryDelay, context.CancellationToken).ConfigureAwait(false);
                }

                (context as RequestContext)?.ResetReplicaResults();
            }
        }
        public void TestSetup()
        {
            request         = Request.Get("foo/bar");
            result          = new ClusterResult(ClusterResultStatus.ReplicasExhausted, new List <ReplicaResult>(), null, request);
            nextModuleCalls = 0;

            context = Substitute.For <IRequestContext>();
            context.Budget.Returns(Budget.Infinite);
            context.Log.Returns(new ConsoleLog());
            context.Request.Returns(request);

            retryPolicy = Substitute.For <IRetryPolicy>();
            retryPolicy.NeedToRetry(Arg.Any <Request>(), Arg.Any <RequestParameters>(), Arg.Any <IList <ReplicaResult> >()).Returns(true);

            retryStrategy = Substitute.For <IRetryStrategy>();
            retryStrategy.AttemptsCount.Returns(MaxAttempts);
            retryStrategy.GetRetryDelay(Arg.Any <int>()).Returns(TimeSpan.Zero);

            module = new RequestRetryModule(retryPolicy, retryStrategy);
        }