RetryEngine
using Polly.Utilities;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Polly.Retry
{
internal static class RetryEngine
{
[System.Runtime.CompilerServices.NullableContext(1)]
[DebuggerDisableUserUnhandledExceptions]
internal static TResult Implementation<[System.Runtime.CompilerServices.Nullable(2)] TResult>(Func<Context, CancellationToken, TResult> action, Context context, ExceptionPredicates shouldRetryExceptionPredicates, ResultPredicates<TResult> shouldRetryResultPredicates, Action<DelegateResult<TResult>, TimeSpan, int, Context> onRetry, CancellationToken cancellationToken, int permittedRetryCount = int.MaxValue, [System.Runtime.CompilerServices.Nullable(2)] IEnumerable<TimeSpan> sleepDurationsEnumerable = null, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1,
1
})] Func<int, DelegateResult<TResult>, Context, TimeSpan> sleepDurationProvider = null)
{
int num = 0;
using (IEnumerator<TimeSpan> enumerator = sleepDurationsEnumerable?.GetEnumerator()) {
while (true) {
cancellationToken.ThrowIfCancellationRequested();
DelegateResult<TResult> delegateResult;
try {
TResult result = action(context, cancellationToken);
if (!shouldRetryResultPredicates.AnyMatch(result))
return result;
if (num >= permittedRetryCount || !(enumerator?.MoveNext() ?? true))
return result;
delegateResult = new DelegateResult<TResult>(result);
} catch (Exception ex) {
Exception ex2 = shouldRetryExceptionPredicates.FirstMatchOrDefault(ex);
if (ex2 == null)
throw;
if (num >= permittedRetryCount || !(enumerator?.MoveNext() ?? true)) {
ex2.RethrowWithOriginalStackTraceIfDiffersFrom(ex);
throw;
}
delegateResult = new DelegateResult<TResult>(ex2);
}
if (num < 2147483647)
num++;
TimeSpan timeSpan = (enumerator != null) ? enumerator.Current : (sleepDurationProvider?.Invoke(num, delegateResult, context) ?? TimeSpan.Zero);
onRetry(delegateResult, timeSpan, num, context);
if (timeSpan > TimeSpan.Zero)
SystemClock.Sleep(timeSpan, cancellationToken);
}
}
}
}
}