示例#1
0
 public static async Task Retry(this IRetryPolicy retryPolicy, Func <Task> retryMethod, CancellationToken cancellationToken = default(CancellationToken))
 {
     using (var retryContext = retryPolicy.GetRetryContext())
     {
         await Attempt(retryContext, retryMethod, cancellationToken).ConfigureAwait(false);
     }
 }
示例#2
0
        async Task Attempt(RetryConsumeContext context, IPipe <ConsumeContext> next)
        {
            context.ClearPendingFaults();

            TimeSpan delay;

            try
            {
                await next.Send(context).ConfigureAwait(false);

                return;
            }
            catch (Exception ex)
            {
                if (!_retryPolicy.CanRetry(ex))
                {
                    context.NotifyPendingFaults();
                    throw;
                }

                // by not adding the retry payload until the exception occurs, the deepest retry filter
                // is the one to set the actual retry context with the deepest configured policy
                IRetryContext retryContext = context.GetOrAddPayload(() => _retryPolicy.GetRetryContext());
                if (!retryContext.CanRetry(ex, out delay))
                {
                    context.NotifyPendingFaults();
                    throw;
                }
            }

            await Task.Delay(delay).ConfigureAwait(false);

            await Attempt(context, next).ConfigureAwait(false);
        }
示例#3
0
        public async Task Send(ConsumeContext <T> context, IPipe <ConsumeContext <T> > next)
        {
            try
            {
                await next.Send(context);
            }
            catch (Exception ex)
            {
                if (!_retryPolicy.CanRetry(ex))
                {
                    throw;
                }

                try
                {
                    MessageRedeliveryContext redeliveryContext;
                    if (!context.TryGetPayload(out redeliveryContext))
                    {
                        throw new ContextException("The message redelivery context was not available to delay the message", ex);
                    }

                    TimeSpan delay;
                    using (IRetryContext retryContext = _retryPolicy.GetRetryContext())
                    {
                        retryContext.CanRetry(ex, out delay);
                    }

                    await redeliveryContext.ScheduleRedelivery(delay);
                }
                catch (Exception redeliveryException)
                {
                    throw new ContextException("The message delivery could not be rescheduled", new AggregateException(redeliveryException, ex));
                }
            }
        }
 public static async Task Retry <T>(this IRetryPolicy retryPolicy, ConsumeContext <T> context,
                                    Func <ConsumeContext <T>, Task> retryMethod)
     where T : class
 {
     using (IRetryContext retryContext = retryPolicy.GetRetryContext())
     {
         await Attempt(retryContext, context, retryMethod).ConfigureAwait(false);
     }
 }
示例#5
0
        public static async Task RetryUntilCancelled(this IRetryPolicy retryPolicy, Func <Task> retryMethod,
                                                     CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Yield();

            while (!cancellationToken.IsCancellationRequested)
            {
                using (var retryContext = retryPolicy.GetRetryContext())
                {
                    await Attempt(retryContext, retryMethod, cancellationToken).ConfigureAwait(false);
                }
            }
        }
示例#6
0
        /// <summary>
        /// Retry a task composition using the specified retry policy
        /// </summary>
        /// <typeparam name="T">The composer payload type</typeparam>
        /// <param name="composer">The task composer</param>
        /// <param name="retryPolicy">The retry policy</param>
        /// <param name="callback">The task composition callback</param>
        /// <returns>The original task composer</returns>
        public static Composer <T> Retry <T>(this Composer <T> composer, IRetryPolicy retryPolicy, Action <Composer <T> > callback)
        {
            IRetryContext retryContext = null;

            composer.ComposeTask(taskComposer =>
            {
                retryContext = retryPolicy.GetRetryContext();

                Attempt(taskComposer, retryContext, callback);
            });

            composer.Finally((_, status) =>
            {
                if (retryContext != null)
                {
                    retryContext.Complete(status);
                }
            });

            return(composer);
        }
示例#7
0
 public IRetryContext GetRetryContext()
 {
     return(new CancelRetryContext(_retryPolicy.GetRetryContext(), _cancellationToken));
 }