async Task IFilter <TContext> .Send(TContext context, IPipe <TContext> next) { RetryPolicyContext <TContext> policyContext = _retryPolicy.CreatePolicyContext(context); await _observers.PostCreate(policyContext).ConfigureAwait(false); try { await next.Send(policyContext.Context).ConfigureAwait(false); } catch (Exception exception) { RetryContext <TContext> payloadRetryContext; if (context.TryGetPayload(out payloadRetryContext)) { await policyContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(payloadRetryContext).ConfigureAwait(false); throw; } RetryContext genericRetryContext; if (context.TryGetPayload(out genericRetryContext)) { await policyContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(genericRetryContext).ConfigureAwait(false); throw; } RetryContext <TContext> retryContext; if (!policyContext.CanRetry(exception, out retryContext)) { await retryContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(retryContext).ConfigureAwait(false); context.GetOrAddPayload(() => retryContext); throw; } await _observers.PostFault(retryContext).ConfigureAwait(false); if (retryContext.Delay.HasValue) { await Task.Delay(retryContext.Delay.Value).ConfigureAwait(false); } await Attempt(retryContext, next).ConfigureAwait(false); } }
async Task IFilter <TContext> .Send(TContext context, IPipe <TContext> next) { using (RetryPolicyContext <TContext> policyContext = _retryPolicy.CreatePolicyContext(context)) { await _observers.PostCreate(policyContext).ConfigureAwait(false); try { await next.Send(policyContext.Context).ConfigureAwait(false); } catch (OperationCanceledException exception) when(exception.CancellationToken == policyContext.Context.CancellationToken || exception.CancellationToken == context.CancellationToken) { throw; } catch (Exception exception) { if (policyContext.Context.CancellationToken.IsCancellationRequested) { policyContext.Context.CancellationToken.ThrowIfCancellationRequested(); } if (policyContext.Context.TryGetPayload(out RetryContext <TContext> payloadRetryContext)) { if (_retryPolicy.IsHandled(exception)) { await policyContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(payloadRetryContext).ConfigureAwait(false); } context.GetOrAddPayload(() => payloadRetryContext); throw; } if (policyContext.Context.TryGetPayload(out RetryContext genericRetryContext)) { if (_retryPolicy.IsHandled(exception)) { await policyContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(genericRetryContext).ConfigureAwait(false); } context.GetOrAddPayload(() => genericRetryContext); throw; } if (!policyContext.CanRetry(exception, out RetryContext <TContext> retryContext)) { if (_retryPolicy.IsHandled(exception)) { await retryContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(retryContext).ConfigureAwait(false); context.GetOrAddPayload(() => retryContext); } throw; } await _observers.PostFault(retryContext).ConfigureAwait(false); await Attempt(context, retryContext, next).ConfigureAwait(false); } } }
public async Task Send(ConsumeContext <T> context, IPipe <ConsumeContext <T> > next) { RetryPolicyContext <ConsumeContext <T> > policyContext = _retryPolicy.CreatePolicyContext(context); await _observers.PostCreate(policyContext).ConfigureAwait(false); try { await next.Send(policyContext.Context).ConfigureAwait(false); } catch (Exception exception) { if (context.CancellationToken.IsCancellationRequested) { if (exception is OperationCanceledException canceledException && canceledException.CancellationToken == context.CancellationToken) { throw; } context.CancellationToken.ThrowIfCancellationRequested(); } if (policyContext.Context.TryGetPayload(out RetryContext <ConsumeContext <T> > payloadRetryContext)) { await policyContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(payloadRetryContext).ConfigureAwait(false); context.GetOrAddPayload(() => payloadRetryContext); throw; } if (policyContext.Context.TryGetPayload(out RetryContext genericRetryContext)) { await policyContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(genericRetryContext).ConfigureAwait(false); context.GetOrAddPayload(() => genericRetryContext); throw; } if (!policyContext.CanRetry(exception, out RetryContext <ConsumeContext <T> > retryContext)) { await retryContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(retryContext).ConfigureAwait(false); if (_retryPolicy.IsHandled(exception)) { context.GetOrAddPayload(() => retryContext); } throw; } int previousDeliveryCount = context.Headers.Get(MessageHeaders.RedeliveryCount, default(int?)) ?? 0; for (int retryIndex = 0; retryIndex < previousDeliveryCount; retryIndex++) { if (!retryContext.CanRetry(exception, out retryContext)) { await retryContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(retryContext).ConfigureAwait(false); if (_retryPolicy.IsHandled(exception)) { context.GetOrAddPayload(() => retryContext); } throw; } } await _observers.PostFault(retryContext).ConfigureAwait(false); try { if (!context.TryGetPayload(out MessageRedeliveryContext redeliveryContext)) { throw new ContextException("The message redelivery context was not available to delay the message", exception); } var delay = retryContext.Delay ?? TimeSpan.Zero; await redeliveryContext.ScheduleRedelivery(delay).ConfigureAwait(false); await context.NotifyConsumed(context, context.ReceiveContext.ElapsedTime, TypeMetadataCache <RedeliveryRetryFilter <T> > .ShortName).ConfigureAwait(false); } catch (Exception redeliveryException) { throw new ContextException("The message delivery could not be rescheduled", new AggregateException(redeliveryException, exception)); } } }
public async Task Send(TContext context, IPipe <TContext> next) { using (RetryPolicyContext <TContext> policyContext = _retryPolicy.CreatePolicyContext(context)) { if (_observers.Count > 0) { await _observers.PostCreate(policyContext).ConfigureAwait(false); } try { await next.Send(policyContext.Context).ConfigureAwait(false); } catch (OperationCanceledException exception) when(exception.CancellationToken == context.CancellationToken || exception.CancellationToken == policyContext.Context.CancellationToken) { throw; } catch (Exception exception) { if (policyContext.Context.CancellationToken.IsCancellationRequested) { policyContext.Context.CancellationToken.ThrowIfCancellationRequested(); } if (!policyContext.CanRetry(exception, out RetryContext <TContext> retryContext)) { if (_retryPolicy.IsHandled(exception)) { context.GetOrAddPayload(() => retryContext); await retryContext.RetryFaulted(exception).ConfigureAwait(false); if (_observers.Count > 0) { await _observers.RetryFault(retryContext).ConfigureAwait(false); } } throw; } var previousDeliveryCount = context.GetRedeliveryCount(); for (var retryIndex = 0; retryIndex < previousDeliveryCount; retryIndex++) { if (!retryContext.CanRetry(exception, out retryContext)) { if (_retryPolicy.IsHandled(exception)) { context.GetOrAddPayload(() => retryContext); await retryContext.RetryFaulted(exception).ConfigureAwait(false); if (_observers.Count > 0) { await _observers.RetryFault(retryContext).ConfigureAwait(false); } } throw; } } if (_observers.Count > 0) { await _observers.PostFault(retryContext).ConfigureAwait(false); } try { var redeliveryContext = context.GetPayload <MessageRedeliveryContext>(); var delay = retryContext.Delay ?? TimeSpan.Zero; await redeliveryContext.ScheduleRedelivery(delay).ConfigureAwait(false); await context.NotifyConsumed(context, context.ReceiveContext.ElapsedTime, TypeMetadataCache <RedeliveryRetryFilter <TContext, TMessage> > .ShortName).ConfigureAwait(false); } catch (Exception redeliveryException) { throw new TransportException(context.ReceiveContext.InputAddress, "The message delivery could not be rescheduled", new AggregateException(redeliveryException, exception)); } } } }
public async Task Send(ConsumeContext <T> context, IPipe <ConsumeContext <T> > next) { RetryPolicyContext <ConsumeContext <T> > policyContext = _retryPolicy.CreatePolicyContext(context); await _observers.PostCreate(policyContext).ConfigureAwait(false); try { await next.Send(policyContext.Context).ConfigureAwait(false); } catch (Exception exception) { RetryContext <ConsumeContext <T> > payloadRetryContext; if (context.TryGetPayload(out payloadRetryContext)) { await policyContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(payloadRetryContext).ConfigureAwait(false); throw; } RetryContext genericRetryContext; if (context.TryGetPayload(out genericRetryContext)) { await policyContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(genericRetryContext).ConfigureAwait(false); throw; } RetryContext <ConsumeContext <T> > retryContext; if (!policyContext.CanRetry(exception, out retryContext)) { await retryContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(retryContext).ConfigureAwait(false); context.GetOrAddPayload(() => retryContext); throw; } int previousDeliveryCount = context.Headers.Get(MessageHeaders.RedeliveryCount, default(int?)) ?? 0; for (int retryIndex = 0; retryIndex < previousDeliveryCount; retryIndex++) { if (!retryContext.CanRetry(exception, out retryContext)) { await retryContext.RetryFaulted(exception).ConfigureAwait(false); await _observers.RetryFault(retryContext).ConfigureAwait(false); context.GetOrAddPayload(() => retryContext); throw; } } await _observers.PostFault(retryContext).ConfigureAwait(false); try { MessageRedeliveryContext redeliveryContext; if (!context.TryGetPayload(out redeliveryContext)) { throw new ContextException("The message redelivery context was not available to delay the message", exception); } var delay = retryContext.Delay ?? TimeSpan.Zero; await redeliveryContext.ScheduleRedelivery(delay).ConfigureAwait(false); } catch (Exception redeliveryException) { throw new ContextException("The message delivery could not be rescheduled", new AggregateException(redeliveryException, exception)); } } }