<PackageReference Include="System.ClientModel" Version="1.3.0" />

ClientRetryPolicy

A PipelinePolicy used by a ClientPipeline to decide whether or not to retry a PipelineRequest.
using Microsoft.Extensions.Logging; using System.ClientModel.Internal; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; namespace System.ClientModel.Primitives { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public class ClientRetryPolicy : PipelinePolicy { private static readonly TimeSpan DefaultInitialDelay = TimeSpan.FromSeconds(0.8); private readonly int _maxRetries; private readonly TimeSpan _initialDelay; [System.Runtime.CompilerServices.Nullable(2)] private readonly PipelineRetryLogger _retryLogger; internal const int DefaultMaxRetries = 3; public static ClientRetryPolicy Default { get; } = new ClientRetryPolicy(3); public ClientRetryPolicy(int maxRetries = 3) : this(maxRetries, true, null) { } [System.Runtime.CompilerServices.NullableContext(2)] public ClientRetryPolicy(int maxRetries, bool enableLogging, ILoggerFactory loggerFactory) { _maxRetries = maxRetries; _initialDelay = DefaultInitialDelay; _retryLogger = (enableLogging ? new PipelineRetryLogger(loggerFactory) : null); } public sealed override void Process(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex) { ProcessSyncOrAsync(message, pipeline, currentIndex, false).EnsureCompleted(); } [AsyncStateMachine(typeof(<ProcessAsync>d__11))] public sealed override ValueTask ProcessAsync(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex) { <ProcessAsync>d__11 stateMachine = default(<ProcessAsync>d__11); stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create(); stateMachine.<>4__this = this; stateMachine.message = message; stateMachine.pipeline = pipeline; stateMachine.currentIndex = currentIndex; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } [AsyncStateMachine(typeof(<ProcessSyncOrAsync>d__12))] private ValueTask ProcessSyncOrAsync(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex, bool async) { <ProcessSyncOrAsync>d__12 stateMachine = default(<ProcessSyncOrAsync>d__12); stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create(); stateMachine.<>4__this = this; stateMachine.message = message; stateMachine.pipeline = pipeline; stateMachine.currentIndex = currentIndex; stateMachine.async = async; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } protected virtual void OnSendingRequest(PipelineMessage message) { } protected virtual ValueTask OnSendingRequestAsync(PipelineMessage message) { return default(ValueTask); } protected virtual void OnRequestSent(PipelineMessage message) { } protected virtual ValueTask OnRequestSentAsync(PipelineMessage message) { return default(ValueTask); } protected virtual void OnTryComplete(PipelineMessage message) { } internal bool ShouldRetryInternal(PipelineMessage message, [System.Runtime.CompilerServices.Nullable(2)] Exception exception) { return ShouldRetryInternalSyncOrAsync(message, exception, false).EnsureCompleted(); } [System.Runtime.CompilerServices.NullableContext(0)] [AsyncStateMachine(typeof(<ShouldRetryInternalAsync>d__19))] internal ValueTask<bool> ShouldRetryInternalAsync([System.Runtime.CompilerServices.Nullable(1)] PipelineMessage message, [System.Runtime.CompilerServices.Nullable(2)] Exception exception) { <ShouldRetryInternalAsync>d__19 stateMachine = default(<ShouldRetryInternalAsync>d__19); stateMachine.<>t__builder = AsyncValueTaskMethodBuilder<bool>.Create(); stateMachine.<>4__this = this; stateMachine.message = message; stateMachine.exception = exception; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } [System.Runtime.CompilerServices.NullableContext(0)] [AsyncStateMachine(typeof(<ShouldRetryInternalSyncOrAsync>d__20))] private ValueTask<bool> ShouldRetryInternalSyncOrAsync([System.Runtime.CompilerServices.Nullable(1)] PipelineMessage message, [System.Runtime.CompilerServices.Nullable(2)] Exception exception, bool async) { <ShouldRetryInternalSyncOrAsync>d__20 stateMachine = default(<ShouldRetryInternalSyncOrAsync>d__20); stateMachine.<>t__builder = AsyncValueTaskMethodBuilder<bool>.Create(); stateMachine.<>4__this = this; stateMachine.message = message; stateMachine.exception = exception; stateMachine.async = async; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } protected virtual bool ShouldRetry(PipelineMessage message, [System.Runtime.CompilerServices.Nullable(2)] Exception exception) { if (message.RetryCount >= _maxRetries) return false; if (!message.ResponseClassifier.TryClassify(message, exception, out bool isRetriable)) PipelineMessageClassifier.Default.TryClassify(message, exception, out isRetriable); return isRetriable; } [System.Runtime.CompilerServices.NullableContext(0)] protected virtual ValueTask<bool> ShouldRetryAsync([System.Runtime.CompilerServices.Nullable(1)] PipelineMessage message, [System.Runtime.CompilerServices.Nullable(2)] Exception exception) { return new ValueTask<bool>(ShouldRetry(message, exception)); } protected virtual TimeSpan GetNextDelay(PipelineMessage message, int tryCount) { double num = (double)(1 << tryCount - 1) * _initialDelay.TotalMilliseconds; TimeSpan value; if (message.Response != null && PipelineResponseHeaders.TryGetRetryAfter(message.Response, out value) && value.TotalMilliseconds > num) return value; return TimeSpan.FromMilliseconds(num); } [AsyncStateMachine(typeof(<WaitAsync>d__24))] protected virtual Task WaitAsync(TimeSpan time, CancellationToken cancellationToken) { <WaitAsync>d__24 stateMachine = default(<WaitAsync>d__24); stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create(); stateMachine.time = time; stateMachine.cancellationToken = cancellationToken; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } protected virtual void Wait(TimeSpan time, CancellationToken cancellationToken) { if (cancellationToken.WaitHandle.WaitOne(time)) CancellationHelper.ThrowIfCancellationRequested(cancellationToken, null); } } }