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