/// <summary> /// Repetitively executes the specified action while it satisfies the current retry policy. /// </summary> /// <typeparam name="TResult">The type of result expected from the executable action.</typeparam> /// <param name="func">A delegate that represents the executable action that returns the result of type <typeparamref name="TResult" />.</param> /// <returns>The result from the action.</returns> public virtual TResult ExecuteAction <TResult>(Func <TResult> func) { TResult tResult; Guard.ArgumentNotNull(func, "func"); var num = 0; var shouldRetry = RetryStrategy.GetShouldRetry(); while (true) { try { tResult = func(); break; } #pragma warning disable CS0618 // Type or member is obsolete catch (RetryLimitExceededException retryLimitExceededException) #pragma warning restore CS0618 // Type or member is obsolete { if (retryLimitExceededException.InnerException != null) { throw retryLimitExceededException.InnerException; } tResult = default(TResult); break; } catch (Exception exception) { if (ErrorDetectionStrategy.IsTransient(exception)) { var num1 = num; num = num1 + 1; TimeSpan zero; if (shouldRetry(num1, exception, out zero)) { if (zero.TotalMilliseconds < 0) { zero = TimeSpan.Zero; } OnRetrying(num, exception, zero); if (num > 1 || !RetryStrategy.FastFirstRetry) { Task.Delay(zero).Wait(); } } } throw; } } return(tResult); }
/// <summary> /// Executes the action. /// </summary> /// <typeparam name="TResult">The type of the t result.</typeparam> /// <param name="func">The function.</param> /// <returns>TResult.</returns> /// <exception cref="System.ArgumentNullException">func</exception> public override TResult ExecuteAction <TResult>(Func <TResult> func) { //Converting func,if RetryPolicyAdapter defined var adaptedFunction = RetryPolicyAdapter != null?RetryPolicyAdapter.AdaptExecuteAction(func) : func; if (func == null) { throw new ArgumentNullException("func"); } int retryCount = 0; TimeSpan delay = TimeSpan.Zero; ShouldRetry shouldRetry = RetryStrategy.GetShouldRetry(); while (true) { do { try { return(adaptedFunction()); } catch (Exception ex) { if (!ErrorDetectionStrategy.IsTransient(ex)) { throw; } if (shouldRetry(retryCount++, ex, out delay)) { if (delay.TotalMilliseconds < 0.0) { delay = TimeSpan.Zero; } OnRetrying(retryCount, ex, delay); } else { OnRetrying(retryCount, ex, delay); throw; } } }while (retryCount <= 1 && RetryStrategy.FastFirstRetry); Thread.Sleep(delay); } }
public bool ShouldIgnoreError(RetryState retryState) { bool shouldIgnoreError = ErrorDetectionStrategy.ShouldIgnoreError(retryState.LastError); Logger.Write(LogLevel.Error, string.Format( CultureInfo.InvariantCulture, "Ignore Error requested: Retry count = {0}. Delay = {1}, SQL Error Number = {2}, Should Ignore Error = {3}", retryState.RetryCount, retryState.Delay, GetErrorNumber(retryState.LastError), shouldIgnoreError)); return(shouldIgnoreError); }
public bool ShouldRetry(RetryState retryState) { bool canRetry = ErrorDetectionStrategy.CanRetry(retryState.LastError); bool shouldRetry = canRetry && ShouldRetryImpl(retryState); Logger.Write(LogLevel.Error, string.Format( CultureInfo.InvariantCulture, "Retry requested: Retry count = {0}. Delay = {1}, SQL Error Number = {2}, Can retry error = {3}, Will retry = {4}", retryState.RetryCount, retryState.Delay, GetErrorNumber(retryState.LastError), canRetry, shouldRetry)); // Perform an extra check in the delay interval. Should prevent from accidentally ending up with the value of -1 which will block a thread indefinitely. // In addition, any other negative numbers will cause an ArgumentOutOfRangeException fault which will be thrown by Thread.Sleep. if (retryState.Delay.TotalMilliseconds < 0) { retryState.Delay = TimeSpan.Zero; } return(shouldRetry); }
public bool IsRetryableException(Exception ex) { return(ErrorDetectionStrategy.CanRetry(ex)); }
public FailedEndpoint(string id, string name, string iotHubName, Exception exception, ErrorDetectionStrategy detectionStrategy) : base(id, name, iotHubName) { this.Exception = exception; this.detectionStrategy = detectionStrategy; }