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