Beispiel #1
0
        async Task Attempt(RetryContext <TContext> retryContext, IPipe <TContext> next)
        {
            await retryContext.PreRetry().ConfigureAwait(false);

            await _observers.PreRetry(retryContext).ConfigureAwait(false);

            try
            {
                await next.Send(retryContext.Context).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                RetryContext <TContext> payloadRetryContext;
                if (retryContext.Context.TryGetPayload(out payloadRetryContext))
                {
                    await retryContext.RetryFaulted(exception).ConfigureAwait(false);

                    await _observers.RetryFault(payloadRetryContext).ConfigureAwait(false);

                    throw;
                }

                RetryContext genericRetryContext;
                if (retryContext.Context.TryGetPayload(out genericRetryContext))
                {
                    await retryContext.RetryFaulted(exception).ConfigureAwait(false);

                    await _observers.RetryFault(genericRetryContext).ConfigureAwait(false);

                    throw;
                }

                RetryContext <TContext> nextRetryContext;
                if (!retryContext.CanRetry(exception, out nextRetryContext))
                {
                    await nextRetryContext.RetryFaulted(exception).ConfigureAwait(false);

                    await _observers.RetryFault(nextRetryContext).ConfigureAwait(false);

                    retryContext.Context.GetOrAddPayload(() => nextRetryContext);

                    throw;
                }

                await _observers.PostFault(nextRetryContext).ConfigureAwait(false);

                if (nextRetryContext.Delay.HasValue)
                {
                    await Task.Delay(nextRetryContext.Delay.Value).ConfigureAwait(false);
                }

                await Attempt(nextRetryContext, next).ConfigureAwait(false);
            }
        }
Beispiel #2
0
        async Task Attempt(TContext context, RetryContext <TContext> retryContext, IPipe <TContext> next)
        {
            while (retryContext.CancellationToken.IsCancellationRequested == false)
            {
                if (retryContext.Delay.HasValue)
                {
                    await Task.Delay(retryContext.Delay.Value, retryContext.CancellationToken).ConfigureAwait(false);
                }

                await retryContext.PreRetry().ConfigureAwait(false);

                await _observers.PreRetry(retryContext).ConfigureAwait(false);

                try
                {
                    await next.Send(retryContext.Context).ConfigureAwait(false);

                    return;
                }
                catch (OperationCanceledException exception)
                    when(exception.CancellationToken == retryContext.CancellationToken || exception.CancellationToken == context.CancellationToken)
                    {
                        throw;
                    }
                catch (Exception exception)
                {
                    if (context.CancellationToken.IsCancellationRequested)
                    {
                        context.CancellationToken.ThrowIfCancellationRequested();
                    }

                    if (retryContext.Context.TryGetPayload(out RetryContext <TContext> payloadRetryContext))
                    {
                        if (_retryPolicy.IsHandled(exception))
                        {
                            await retryContext.RetryFaulted(exception).ConfigureAwait(false);

                            await _observers.RetryFault(payloadRetryContext).ConfigureAwait(false);
                        }

                        context.GetOrAddPayload(() => payloadRetryContext);

                        throw;
                    }

                    if (retryContext.Context.TryGetPayload(out RetryContext genericRetryContext))
                    {
                        if (_retryPolicy.IsHandled(exception))
                        {
                            await retryContext.RetryFaulted(exception).ConfigureAwait(false);

                            await _observers.RetryFault(genericRetryContext).ConfigureAwait(false);
                        }

                        context.GetOrAddPayload(() => genericRetryContext);

                        throw;
                    }

                    if (!retryContext.CanRetry(exception, out RetryContext <TContext> nextRetryContext))
                    {
                        if (_retryPolicy.IsHandled(exception))
                        {
                            await nextRetryContext.RetryFaulted(exception).ConfigureAwait(false);

                            await _observers.RetryFault(nextRetryContext).ConfigureAwait(false);

                            context.GetOrAddPayload(() => nextRetryContext);
                        }

                        throw;
                    }

                    await _observers.PostFault(nextRetryContext).ConfigureAwait(false);

                    retryContext = nextRetryContext;
                }
            }

            context.CancellationToken.ThrowIfCancellationRequested();
        }