public async Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func <Task> next) { ExceptionDispatchInfo serializationException = null; try { await next() .ConfigureAwait(false); } catch (Exception exception) { if (IsRetryCountReached(context)) { // We can't do async in a catch block, therefore we have to capture the exception! serializationException = ExceptionDispatchInfo.Capture(exception); } else { throw; } } if (serializationException != null) { var message = context.TransportMessage; message.SetFailureHeaders(serializationException.SourceException, "Max number of retries has been reached!"); await message.DeadLetterAsync() .ConfigureAwait(false); // Because we instructed the message to deadletter it is safe to rethrow. The broker will not redeliver. serializationException.Throw(); } }
public async Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func <Task> next) { ExceptionDispatchInfo exceptionDispatchInfo = null; try { await next() .ConfigureAwait(false); } catch (Exception exception) { if (ShouldMessageBeDelayed(context)) { // We can't do async in a catch block, therefore we have to capture the exception! exceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception); } else { throw; } } if (exceptionDispatchInfo != null) { var message = context.TransportMessage; var scheduledEnqueueTimeUtc = DateTime.UtcNow + TimeSpan.FromSeconds(DelayTimeSpanInSeconds(context)); message.DelayedDeliveryCount++; await bus.Postpone(context.LogicalMessage.Instance, scheduledEnqueueTimeUtc); // Don't rethrow, the current message is consumed and a new message is postponed. } }
public async Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func <Task> next) { var messageType = context.LogicalMessage.Instance.GetType(); var handlers = this.registry.GetHandlers(messageType); foreach (var handler in handlers) { using (context.CreateSnapshot()) { var messageHandler = new MessageHandler { Instance = handler, Invocation = (handlerInstance, message) => this.registry.InvokeHandle(handlerInstance, message, bus) }; context.Handler = messageHandler; await next() .ConfigureAwait(false); if (context.HandlerInvocationAbortPending) { break; } } } }
public async Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func <Task> next) { ExceptionDispatchInfo exceptionDispatchInfo = null; try { await next() .ConfigureAwait(false); } catch (DeadletterMessageImmediatelyException exception) { // We can't do async in a catch block, therefore we have to capture the exception! exceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception); } if (HandleMessageCriticalExceptionHasBeenCaught(exceptionDispatchInfo)) { var message = context.TransportMessage; // ReSharper disable PossibleNullReferenceException var exceptionToHeader = exceptionDispatchInfo.SourceException.InnerException ?? exceptionDispatchInfo.SourceException; message.SetFailureHeaders(exceptionToHeader, "Message is deadlettered immediately on DeadletterMessageImmediatelyException"); // ReSharper restore PossibleNullReferenceException await message.DeadLetterAsync() .ConfigureAwait(false); // Because we instructed the message to deadletter it is safe to rethrow. The broker will not redeliver. // Already deadlettered message should not be unlocked - throw for it exceptionDispatchInfo.Throw(); } }
public async Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func<Task> next) { ExceptionDispatchInfo serializationException = null; try { await next() .ConfigureAwait(false); } catch (Exception exception) { if (IsRetryCountReached(context)) { // We can't do async in a catch block, therefore we have to capture the exception! serializationException = ExceptionDispatchInfo.Capture(exception); } else { throw; } } if (serializationException != null) { var message = context.TransportMessage; message.SetFailureHeaders(serializationException.SourceException, "Max number of retries has been reached!"); await message.DeadLetterAsync() .ConfigureAwait(false); // Because we instructed the message to deadletter it is safe to rethrow. The broker will not redeliver. serializationException.Throw(); } }
public async Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func<Task> next) { var messageType = context.LogicalMessage.Instance.GetType(); var handlers = this.registry.GetHandlers(messageType); foreach (var handler in handlers) { using (context.CreateSnapshot()) { var messageHandler = new MessageHandler { Instance = handler, Invocation = (handlerInstance, message) => this.registry.InvokeHandle(handlerInstance, message, bus) }; context.Handler = messageHandler; await next() .ConfigureAwait(false); if (context.HandlerInvocationAbortPending) { break; } } } }
public async Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func <Task> next) { var messageHandler = context.Handler; await messageHandler.Invocation(messageHandler.Instance, context.LogicalMessage.Instance) .ConfigureAwait(false); await next() .ConfigureAwait(false); }
public async Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func<Task> next) { var messageHandler = context.Handler; await messageHandler.Invocation(messageHandler.Instance, context.LogicalMessage.Instance) .ConfigureAwait(false); await next() .ConfigureAwait(false); }
private Task InvokeLogical(IncomingLogicalContext context, IBusForHandler bus) { if (this.executingLogicalPipeline.Count == 0) { return(Task.FromResult(0)); } IIncomingLogicalStep step = this.executingLogicalPipeline.Dequeue(); return(step.Invoke(context, bus, () => this.InvokeLogical(context, bus))); }
public async Task Invoke(IBusForHandler bus, TransportMessage message, EndpointConfiguration.ReadOnly configuration) { this.executingTransportPipeline = new Queue <IIncomingTransportStep>(this.registeredTransportPipeline); var transportContext = new IncomingTransportContext(message, configuration); transportContext.SetChain(this); await this.InvokeTransport(transportContext, bus) .ConfigureAwait(false); // We assume that someone in the pipeline made logical message var logicalMessage = transportContext.Get <LogicalMessage>(); this.executingLogicalPipeline = new Queue <IIncomingLogicalStep>(this.registeredLogicalPipeline); var logicalContext = new IncomingLogicalContext(logicalMessage, message, configuration); logicalContext.SetChain(this); this.currentContext = logicalContext; await this.InvokeLogical(logicalContext, bus) .ConfigureAwait(false); }
public Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func<Task> next) { var step = this.factory(); return step.Invoke(context, bus, next); }
public async Task Invoke(IBusForHandler bus, TransportMessage message, EndpointConfiguration.ReadOnly configuration) { this.executingTransportPipeline = new Queue<IIncomingTransportStep>(this.registeredTransportPipeline); var transportContext = new IncomingTransportContext(message, configuration); transportContext.SetChain(this); await this.InvokeTransport(transportContext, bus) .ConfigureAwait(false); // We assume that someone in the pipeline made logical message var logicalMessage = transportContext.Get<LogicalMessage>(); this.executingLogicalPipeline = new Queue<IIncomingLogicalStep>(this.registeredLogicalPipeline); var logicalContext = new IncomingLogicalContext(logicalMessage, message, configuration); logicalContext.SetChain(this); this.currentContext = logicalContext; await this.InvokeLogical(logicalContext, bus) .ConfigureAwait(false); }
private static bool IsRetryCountReached(IncomingLogicalContext context) { return(context.TransportMessage.DeliveryCount >= context.Configuration.ImmediateRetryCount && context.TransportMessage.DelayedDeliveryCount == context.Configuration.DelayedRetryCount); }
private static double DelayTimeSpanInSeconds(IncomingLogicalContext context) { return(Math.Pow(2, context.TransportMessage.DelayedDeliveryCount)); }
public Task Invoke(IncomingLogicalContext context, IBusForHandler bus, Func <Task> next) { var step = this.factory(); return(step.Invoke(context, bus, next)); }
private Task InvokeLogical(IncomingLogicalContext context, IBusForHandler bus) { if (this.executingLogicalPipeline.Count == 0) { return Task.FromResult(0); } IIncomingLogicalStep step = this.executingLogicalPipeline.Dequeue(); return step.Invoke(context, bus, () => this.InvokeLogical(context, bus)); }
private static bool IsRetryCountReached(IncomingLogicalContext context) { const int HardcodedMaxRetryOfServiceBusLibrary = 10; return context.TransportMessage.DeliveryCount > HardcodedMaxRetryOfServiceBusLibrary - 1; }
private static bool IsRetryCountReached(IncomingLogicalContext context) { const int HardcodedMaxRetryOfServiceBusLibrary = 10; return(context.TransportMessage.DeliveryCount > HardcodedMaxRetryOfServiceBusLibrary - 1); }