예제 #1
0
 public Task <bool> HandleRetryAsync(FailedMessageHandlingAttempt <TMessageType> attemptInformation)
 {
     Interlocked.Increment(ref this.retryInvokedCount);
     return(TaskHelper.TrueTask);
 }
예제 #2
0
        public override async Task HandleMessageAsync(TMessageType message, CancellationToken token)
        {
            List <Exception> exceptions = null;

            var attempt = 0;

            for (; attempt < this.maxNumberOfAttempts; attempt++)
            {
                Exception lastException;
                try
                {
                    await this.handlerFunc(message, token).ConfigureAwait(false);

                    if (this.successFunc != null)
                    {
                        await this.successFunc(message, attempt + 1, this.maxNumberOfAttempts).ConfigureAwait(false);
                    }

                    return; // success
                }
                catch (Exception exception)
                {
                    if (exceptions == null)
                    {
                        exceptions = new List <Exception>(this.maxNumberOfAttempts);
                    }

                    exceptions.Add(exception);
                    lastException = exception;
                }

                var retryDelay = this.retryDelays[Math.Min(attempt, this.lastRetryDelay)];

                var breakRetryLoop = false;

                if (this.wherePredicates != null)
                {
                    var failedAttempt = new FailedMessageHandlingAttempt <TMessageType>
                    {
                        AttemptNumber          = attempt + 1,
                        Message                = message,
                        CancellationToken      = token,
                        Delay                  = retryDelay,
                        Exception              = lastException,
                        MaximumNumberOfAttemps = this.maxNumberOfAttempts
                    };

                    if (this.wherePredicates.Any(p => p(failedAttempt) == false))
                    {
                        breakRetryLoop = true;
                    }
                }

                if (this.exceptionFunc != null && await this.exceptionFunc(message, lastException, attempt + 1, this.maxNumberOfAttempts, retryDelay, token).ConfigureAwait(false) == false)
                {
                    breakRetryLoop = true;
                }

                if (breakRetryLoop)
                {
                    // ensure the attempt count is correct for the retry failed exception
                    attempt++;
                    break;
                }

                if (attempt != this.maxNumberOfAttempts - 1)
                {
                    // await and then retry
                    await Task.Delay(retryDelay, token).ConfigureAwait(false);
                }
            }

            throw new RetryFailedException("Message handler failed after " + attempt + " attempts. Errors: " + (exceptions != null ? string.Join(",", exceptions.Select((e, i) => (i + 1).ToString() + "." + e.Message)) : string.Empty), attempt, this.retryDelays, exceptions);
        }
예제 #3
0
 public Task <bool> HandleRetryAsync(FailedMessageHandlingAttempt <Message> attemptInformation)
 {
     this.Attempts.Add(attemptInformation.AttemptNumber);
     return(TaskHelper.TrueTask);
 }