Пример #1
0
        private bool IsTransient(ITaskContext task, Exception ex)
        {
            var isTrans = TransientFaultHandling.IsTransient(ex);

            if (!isTrans)
            {
                task.Logger.Warn($"Exception type {ex.GetType()} is not Transient. Msg {ex.Message}");
            }
            return(isTrans);
        }
Пример #2
0
        //public override TU FeatureDecoratorQuery(T message)
        //{
        //    var task = RetryExecuteQuery(message);
        //    return task.Result;
        //}


        void RetryExecute(T message)
        {
            int currentRetry = 0;

            //IRetryableMessage<T> retryable=new RetryableMessage<T>(message){IsRetry = false};
            for (;;)
            {
                try
                {
                    _token.ThrowIfCancellationRequested();

                    _breaker.Invoke(
                        // This is the operation we want to execute.
                        () => Handler?.Handle(message), currentRetry > 0
                        );


                    // Return or break.
                    break;
                }
                catch (CircuitBreakerOpenException e)
                {
                    _token.ThrowIfCancellationRequested();

                    _logger.Warn($"CircuitBreaker '{_name}' Open with internal exception {e.InnerException?.Message}");
                    //Thread.Sleep(Math.Max(_delayInRetries, 100));
                    //await Task.Delay(Math.Min(_delayInRetries, 100));
                    Task.Delay(Math.Min(_delayInRetries, 100)).Wait(_token);
                    //ignore and retry. this is not a genuine error
                }
                catch (AggregateException aex) when(aex.InnerExceptions.Any(r => r is FrameworkException))
                {
                    var fex = aex.InnerExceptions.First(r => r is FrameworkException);
                    //if (fex != null)
                    {
                        ExceptionDispatchInfo.Capture(fex).Throw();
                    }
                }
                catch (Exception ex) when(!(ex is FrameworkException))
                {
                    _token.ThrowIfCancellationRequested();


                    _logger.Error($"Operation Exception in Retry Handler {ex.Message}");

                    Robustness.Instance.SafeCall(() => _errorAction?.Invoke(ex), _logger, "Error invoking error action in RetryHandler {0}");

                    if (_maxRetries.HasValue) //infinite
                    {
                        currentRetry++;
                    }


                    // Check if the exception thrown was a transient exception
                    // based on the logic in the error detection strategy.
                    // Determine whether to retry the operation, as well as how
                    // long to wait, based on the retry strategy.
                    if (_maxRetries.HasValue && ((_maxRetries > 0 && currentRetry > _maxRetries) || !TransientFaultHandling.IsTransient(ex)))
                    {
                        // If this isn't a transient error or we shouldn't retry,
                        // rethrow the exception.
                        throw;
                    }
                }

                // Wait to retry the operation.
                // Consider calculating an exponential delay here and
                // using a strategy best suited for the operation and fault.
                try
                {
                    Task.Delay(_delayInRetries, _token).Wait(_token);
                }
                catch (TaskCanceledException)
                {
                    //cancelled
                }
            }
        }
Пример #3
0
        //public override TU FeatureDecoratorQuery(T message)
        //{
        //    var task = RetryExecuteQuery(message);
        //    return task.Result;
        //}


        void RetryExecute(T message)
        {
            int currentRetry = 0;

            //IRetryableMessage<T> retryable=new RetryableMessage<T>(message){IsRetry = false};
            for (;;)
            {
                try
                {
                    _token.ThrowIfCancellationRequested();

                    Handler?.Handle(message);
                    //await TransientOperationAsync();

                    // Return or break.
                    break;
                }
                catch (Exception ex) when(!(ex is FrameworkException))
                {
                    _token.ThrowIfCancellationRequested();


                    _logger.Error($"Operation Exception in Retry Handler {ex.Message}");

                    Robustness.Instance.SafeCall(() => _errorAction?.Invoke(ex), _logger, "Error invoking error action in RetryHandler {0}");

                    if (_maxRetries.HasValue) //infinite
                    {
                        currentRetry++;
                    }


                    // Check if the exception thrown was a transient exception
                    // based on the logic in the error detection strategy.
                    // Determine whether to retry the operation, as well as how
                    // long to wait, based on the retry strategy.
                    if (_maxRetries.HasValue && ((_maxRetries > 0 && currentRetry > _maxRetries) || !TransientFaultHandling.IsTransient(ex)))
                    {
                        // If this isn't a transient error or we shouldn't retry,
                        // rethrow the exception.
                        throw;
                    }
                }

                // Wait to retry the operation.
                // Consider calculating an exponential delay here and
                // using a strategy best suited for the operation and fault.
                try
                {
                    Task.Delay(_delayInRetries, _token).Wait(_token);
                }
                catch (TaskCanceledException)
                {
                    //cancelled
                }
            }
        }