Exemple #1
0
        public TimeSpan?GetRetryDelay(IRequestContext context, ClusterResult lastResult, int attemptsUsed)
        {
            if (attemptsUsed >= retryStrategy.AttemptsCount)
            {
                return(null);
            }

            return(retryStrategy.GetRetryDelay(attemptsUsed));
        }
        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();
            }
        }
Exemple #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);
        }
        private async Task <string> GetResponse(string url, string body)
        {
            _retryAttempt = 0;
            HttpWebResponse response = null;

            while (response == null)
            {
                try {
                    var webRequest = await url.CreateRequestAsync(body);

                    response = (HttpWebResponse)webRequest.GetResponse();
                    var content = response.GetResponseStream().GetContent();
                    response.Close();
                    return(content);
                } catch (WebException e) {
                    _retryException = e.ToString();
                    response        = e.Response as HttpWebResponse;
                    response?.Close();
                    if (_retryAttempt < _retryCount)
                    {
                        var retryDelay = _retryStrategy.GetRetryDelay(_retryAttempt);
                        await Task.Delay(retryDelay).ConfigureAwait(false);

                        _retryAttempt++;
                        response = null;
                    }
                    else
                    {
                        if (response == null)
                        {
                            throw;
                        }
                    }
                }
            }
            return(null);
        }