示例#1
0
            protected override bool ShouldRetryImpl(RetryState retryStateObj)
            {
                Contract.Assert(retryStateObj is RetryStateEx);
                RetryStateEx retryState = (RetryStateEx)retryStateObj;

                // Calculate the delay as exponential value based on the number of retries.
                retryState.Delay =
                    RetryPolicyUtils.CalcExponentialRetryDelay(
                        retryState.RetryCount,
                        _intervalFactor,
                        _minInterval,
                        _maxInterval);

                // Add the delay to the total retry time
                retryState.TotalRetryTime = retryState.TotalRetryTime + retryState.Delay;

                // Calculate the maximum total retry time depending on how long ago was the task (this retry policy) started.
                // Longer running tasks are less eager to abort since, more work is has been done.
                TimeSpan totalRetryTimeLimit = checked (TimeSpan.FromMilliseconds(
                                                            Math.Max(
                                                                Math.Min(
                                                                    _stopwatch.ElapsedMilliseconds * _totalRetryTimeLimitRate,
                                                                    _maxTotalRetryTimeLimit.TotalMilliseconds),
                                                                _minTotalRetryTimeLimit.TotalMilliseconds)));

                if (retryState.TotalRetryTime <= totalRetryTimeLimit)
                {
                    return(true);
                }

                retryState.Delay = TimeSpan.Zero;
                return(false);
            }
示例#2
0
        /// <summary>
        /// Notifies the subscribers whenever an error is ignored on retry.
        /// </summary>
        /// <param name="retryState">The state of current retry attempt.</param>
        protected virtual void OnIgnoreErrorOccurred(RetryState retryState)
        {
            var ignoreErrorOccurred = IgnoreErrorOccurred;

            if (ignoreErrorOccurred != null)
            {
                ignoreErrorOccurred(retryState);
            }
        }
示例#3
0
        /// <summary>
        /// Notifies the subscribers whenever a retry condition is encountered.
        /// </summary>
        /// <param name="retryState">The state of current retry attempt.</param>
        protected virtual void OnRetryOccurred(RetryState retryState)
        {
            var retryOccurred = RetryOccurred;

            if (retryOccurred != null)
            {
                retryOccurred(retryState);
            }
        }
示例#4
0
        private static void DataConnectionFailureRetry(RetryState retryState)
        {
            Logger.Write(LogLevel.Normal, string.Format(CultureInfo.InvariantCulture,
                                                        "Connection retry number {0}. Delaying {1} ms before retry. Exception: {2}",
                                                        retryState.RetryCount,
                                                        retryState.Delay.TotalMilliseconds.ToString(CultureInfo.InvariantCulture),
                                                        retryState.LastError.ToString()));

            RetryPolicyUtils.RaiseAmbientRetryMessage(retryState, SqlSchemaModelErrorCodes.ServiceActions.ConnectionRetry);
        }
示例#5
0
        private static void CommandFailureIgnore(RetryState retryState, string commandKeyword)
        {
            Logger.Write(LogLevel.Normal, string.Format(
                             CultureInfo.InvariantCulture,
                             "{0} retry number {1}. Ignoring failure. Exception: {2}",
                             commandKeyword,
                             retryState.RetryCount,
                             retryState.LastError.ToString()));

            RetryPolicyUtils.RaiseAmbientIgnoreMessage(retryState, SqlSchemaModelErrorCodes.ServiceActions.CommandRetry);
        }
示例#6
0
        public static void CommandFailureRetry(RetryState retryState, string commandKeyword)
        {
            Logger.Write(TraceEventType.Information, string.Format(
                             CultureInfo.InvariantCulture,
                             "{0} retry number {1}. Delaying {2} ms before retry. Exception: {3}",
                             commandKeyword,
                             retryState.RetryCount,
                             retryState.Delay.TotalMilliseconds.ToString(CultureInfo.InvariantCulture),
                             retryState.LastError.ToString()));

            RetryPolicyUtils.RaiseAmbientRetryMessage(retryState, SqlSchemaModelErrorCodes.ServiceActions.CommandRetry);
        }
示例#7
0
        /// <summary>
        /// Traces the Schema retry information before raising the retry message
        /// </summary>
        /// <param name="retryState"></param>
        /// <param name="errorCode"></param>
        /// <param name="azureSessionId"></param>
        internal static void RaiseSchemaAmbientRetryMessage(RetryState retryState, int errorCode, Guid azureSessionId)
        {
            Logger.Write(LogLevel.Warning, string.Format(
                             "Retry occurred: session: {0}; attempt - {1}; delay - {2}; exception - \"{3}\"",
                             azureSessionId,
                             retryState.RetryCount,
                             retryState.Delay,
                             retryState.LastError
                             ));

            RaiseAmbientRetryMessage(retryState, errorCode);
        }
示例#8
0
            protected override bool ShouldRetryImpl(RetryState retryState)
            {
                Contract.Assert(retryState != null);

                if (IsLessThanMaxRetryCount(retryState.RetryCount, _maxRetryCount))
                {
                    retryState.Delay = _intervalBetweenRetries;
                    return(true);
                }

                retryState.Delay = TimeSpan.Zero;
                return(false);
            }
示例#9
0
            protected override bool ShouldRetryImpl(RetryState retryState)
            {
                Contract.Assert(retryState != null);

                if (IsLessThanMaxRetryCount(retryState.RetryCount, _maxRetryCount))
                {
                    retryState.Delay = RetryPolicyUtils.CalcExponentialRetryDelay(retryState.RetryCount, _intervalFactor, _minInterval, _maxInterval);
                    return(true);
                }

                retryState.Delay = TimeSpan.Zero;
                return(false);
            }
示例#10
0
            protected override bool ShouldRetryImpl(RetryState retryState)
            {
                Contract.Assert(retryState != null);

                if (IsLessThanMaxRetryCount(retryState.RetryCount, _maxRetryCount))
                {
                    retryState.Delay = TimeSpan.FromMilliseconds(_initialInterval.TotalMilliseconds + (_increment.TotalMilliseconds * (retryState.RetryCount - 1)));
                    return(true);
                }

                retryState.Delay = TimeSpan.Zero;
                return(false);
            }
示例#11
0
        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);
        }
示例#12
0
        public static void RaiseAmbientIgnoreMessage(RetryState retryState, int errorCode)
        {
            Action <SqlServerRetryError> retryMsgHandler = AmbientSettings.ConnectionRetryMessageHandler;

            if (retryMsgHandler != null)
            {
                string msg = SqlServerRetryError.FormatIgnoreMessage(
                    retryState.RetryCount,
                    retryState.LastError);

                retryMsgHandler(new SqlServerRetryError(
                                    msg,
                                    retryState.LastError,
                                    retryState.RetryCount,
                                    errorCode,
                                    ErrorSeverity.Warning));
            }
        }
示例#13
0
        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);
        }
示例#14
0
 private void RetryConnectionCallback(RetryState retryState)
 {
     RetryPolicyUtils.RaiseSchemaAmbientRetryMessage(retryState, SqlSchemaModelErrorCodes.ServiceActions.ConnectionRetry, _azureSessionId);
 }
示例#15
0
 private static void ElementCommandFailureIgnore(RetryState retryState)
 {
     CommandFailureIgnore(retryState, "Element Command");
 }
示例#16
0
 private static void CreateDatabaseCommandFailureIgnore(RetryState retryState)
 {
     CommandFailureIgnore(retryState, "Database Command");
 }
示例#17
0
 private static void CommandFailureIgnore(RetryState retryState)
 {
     CommandFailureIgnore(retryState, "Command");
 }
示例#18
0
 private static void CommandFailureRetry(RetryState retryState)
 {
     CommandFailureRetry(retryState, "Command");
 }
示例#19
0
 public static void CreateDatabaseCommandFailureRetry(RetryState retryState)
 {
     CommandFailureRetry(retryState, "Database Command");
 }
示例#20
0
 public static void ElementCommandFailureRetry(RetryState retryState)
 {
     CommandFailureRetry(retryState, "Element Command");
 }
示例#21
0
        /// <summary>
        /// Repetitively executes the specified action while it satisfies the current retry policy.
        /// </summary>
        /// <typeparam name="R">The type of result expected from the executable action.</typeparam>
        /// <param name="func">A delegate representing the executable action which returns the result of type R.</param>
        /// <param name="token">Cancellation token to cancel action between retries.</param>
        /// <returns>The result from the action.</returns>
        public R ExecuteAction <R>(Func <RetryState, R> func, CancellationToken?token = null)
        {
            RetryState retryState = CreateRetryState();

            if (token != null)
            {
                token.Value.ThrowIfCancellationRequested();
            }

            while (true)
            {
                try
                {
                    return(func(retryState));
                }
                catch (RetryLimitExceededException limitExceededEx)
                {
                    // The user code can throw a RetryLimitExceededException to force the exit from the retry loop.
                    // The RetryLimitExceeded exception can have an inner exception attached to it. This is the exception
                    // which we will have to throw up the stack so that callers can handle it.
                    if (limitExceededEx.InnerException != null)
                    {
                        throw limitExceededEx.InnerException;
                    }

                    return(default(R));
                }
                catch (Exception ex)
                {
                    retryState.LastError = ex;

                    if (retryState.RetryCount > 0 || this.ShouldIgnoreOnFirstTry)
                    {
                        // If we can ignore this error, then break out of the loop and consider this execution as passing
                        // We return the default value for the type R
                        if (ShouldIgnoreError(retryState))
                        {
                            OnIgnoreErrorOccurred(retryState);
                            return(default(R));
                        }
                    }

                    retryState.RetryCount++;

                    if (!ShouldRetry(retryState))
                    {
                        throw;
                    }
                }

                OnRetryOccurred(retryState);

                if ((retryState.RetryCount > 1 || !FastFirstRetry) && !retryState.IsDelayDisabled)
                {
                    Thread.Sleep(retryState.Delay);
                }

                // check for cancellation after delay.
                if (token != null)
                {
                    token.Value.ThrowIfCancellationRequested();
                }
            }
        }
示例#22
0
 internal static void CommandFailureRetry(RetryState retryState)
 {
     CommandFailureRetry(retryState, "Command");
 }
示例#23
0
 protected abstract bool ShouldRetryImpl(RetryState retryState);