RetryableErrorsRetryPolicyFactory
using Polly;
using Relativity.Logging;
using System;
using System.Threading.Tasks;
namespace Relativity.DataExchange.Service
{
public class RetryableErrorsRetryPolicyFactory : IKeplerRetryPolicyFactory
{
private readonly IAppSettings settings;
private readonly ILog logger;
private readonly Action<Exception, TimeSpan, int, Context> onRetry;
public RetryableErrorsRetryPolicyFactory(IAppSettings settings, ILog logger)
{
this.settings = settings;
this.logger = logger;
}
public RetryableErrorsRetryPolicyFactory(IAppSettings settings, ILog logger, Action<Exception, TimeSpan, int, Context> onRetry)
{
this.settings = settings;
this.logger = logger;
this.onRetry = onRetry;
}
public IAsyncPolicy CreateRetryPolicy()
{
return RetrySyntaxAsync.WaitAndRetryAsync(Policy.Handle<Exception>((Func<Exception, bool>)IsRetryableException), settings.HttpErrorNumberOfRetries, (Func<int, TimeSpan>)((int retryAttempt) => TimeSpan.FromSeconds((double)settings.HttpErrorWaitTimeInSeconds)), (Func<Exception, TimeSpan, int, Context, Task>)OnRetry);
}
public IAsyncPolicy<T> CreateRetryPolicy<T>()
{
return RetryTResultSyntaxAsync.WaitAndRetryAsync<T>(Policy<Exception>.Handle<Exception>((Func<Exception, bool>)IsRetryableException), settings.HttpErrorNumberOfRetries, (Func<int, TimeSpan>)((int retryAttempt) => TimeSpan.FromSeconds((double)settings.HttpErrorWaitTimeInSeconds)), (Func<DelegateResult<T>, TimeSpan, int, Context, Task>)this.OnRetry<T>);
}
private bool IsRetryableException(Exception exception)
{
if (!ExceptionHelper.IsFatalException(exception) && !ExceptionHelper.IsFatalKeplerException(exception) && !(exception is OperationCanceledException))
return !ExceptionHelper.IsBatchInProgressException(exception);
return false;
}
private Task OnRetry<TResult>(DelegateResult<TResult> result, TimeSpan timeSpan, int retryCount, Context context)
{
return OnRetry(result.get_Exception(), timeSpan, retryCount, context);
}
private Task OnRetry(Exception exception, TimeSpan duration, int retryCount, Context context)
{
if (onRetry == null)
logger.LogWarning(exception, "RetryableErrorsRetryPolicyFactory: Call to Kepler service failed due to {ExceptionType}. Currently on attempt {RetryCount} out of {MaxRetries} and waiting {WaitSeconds} seconds before the next retry attempt.", new object[4] {
exception.GetType(),
retryCount,
AppSettings.Instance.HttpErrorNumberOfRetries,
duration.TotalSeconds
});
else
onRetry(exception, duration, retryCount, context);
return Task.CompletedTask;
}
}
}