示例#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
        internal static void DataConnectionFailureRetry(RetryState retryState)
        {
            Logger.Instance.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
        internal static void CommandFailureIgnore(RetryState retryState, string commandKeyword)
        {
            Logger.Instance.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
        internal 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
            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;
            }
示例#8
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;
            }
示例#9
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;
            }
示例#10
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)
        {
            if (azureSessionId != Guid.Empty)
            {
                Logger.Write(TraceEventType.Warning, string.Format(
                                 "Retry occurred: session: {0}; attempt - {1}; delay - {2}; exception - \"{3}\"",
                                 azureSessionId,
                                 retryState.RetryCount,
                                 retryState.Delay,
                                 retryState.LastError
                                 ));

                RaiseAmbientRetryMessage(retryState, errorCode);
            }
        }
示例#11
0
        public bool ShouldIgnoreError(RetryState retryState)
        {
            bool shouldIgnoreError = ErrorDetectionStrategy.ShouldIgnoreError(retryState.LastError);

            Logger.Instance.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
        internal 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.Instance.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
 internal static void ElementCommandFailureIgnore(RetryState retryState)
 {
     CommandFailureIgnore(retryState, "Element Command");
 }
示例#15
0
 internal static void CreateDatabaseCommandFailureIgnore(RetryState retryState)
 {
     CommandFailureIgnore(retryState, "Database Command");
 }
示例#16
0
 internal static void CommandFailureIgnore(RetryState retryState)
 {
     CommandFailureIgnore(retryState, "Command");
 }
示例#17
0
 internal static void CommandFailureRetry(RetryState retryState)
 {
     CommandFailureRetry(retryState, "Command");
 }
示例#18
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();
                }
            }
        }
 private void RetryConnectionCallback(RetryState retryState)
 {
     RetryPolicyUtils.RaiseSchemaAmbientRetryMessage(retryState, SqlSchemaModelErrorCodes.ServiceActions.ConnectionRetry, _azureSessionId);
 }
示例#20
0
 protected abstract bool ShouldRetryImpl(RetryState retryState);