void DoTry() { var transportMessage = receiveMessages.ReceiveMessage(TransactionContext.Current); if (transportMessage == null) { // to back off and relax when there's no messages to process, we do this nullMessageReceivedBackoffHelper.Wait(); return; } nullMessageReceivedBackoffHelper.Reset(); var id = transportMessage.Id; var label = transportMessage.Label; MessageContext context = null; if (id == null) { HandlePoisonMessage(id, transportMessage); return; } if (errorTracker.MessageHasFailedMaximumNumberOfTimes(id)) { HandlePoisonMessage(id, transportMessage); errorTracker.StopTracking(id); return; } Exception transportMessageExceptionOrNull = null; try { BeforeTransportMessage(transportMessage); // Populate rebus-msg-id, if not set, from transport-level-id if (!transportMessage.Headers.ContainsKey(Headers.MessageId)) { transportMessage.Headers[Headers.MessageId] = transportMessage.Id; } using (var scope = BeginTransaction()) { var message = serializeMessages.Deserialize(transportMessage); // successfully deserialized the transport message, let's enter a message context context = MessageContext.Establish(message.Headers); MessageContextEstablished(context); var unitsOfWork = unitOfWorkManagers.Select(u => u.Create()) .Where(u => !ReferenceEquals(null, u)) .ToArray(); //< remember to invoke the chain here :) try { foreach (var logicalMessage in message.Messages.Select(MutateIncoming)) { context.SetLogicalMessage(logicalMessage); Exception logicalMessageExceptionOrNull = null; try { BeforeMessage(logicalMessage); var typeToDispatch = logicalMessage.GetType(); messageLogger.LogReceive(id, logicalMessage); try { var dispatchMethod = GetDispatchMethod(typeToDispatch); var parameters = new[] { logicalMessage }; dispatchMethod.Invoke(this, parameters); } catch (TargetInvocationException tie) { var exception = tie.InnerException; exception.PreserveStackTrace(); throw exception; } } catch (Exception exception) { logicalMessageExceptionOrNull = exception; throw; } finally { try { AfterMessage(logicalMessageExceptionOrNull, logicalMessage); } catch (Exception exceptionWhileRaisingEvent) { if (logicalMessageExceptionOrNull != null) { log.Error( "An exception occurred while raising the AfterMessage event, and an exception occurred some" + " time before that as well. The first exception was this: {0}. And then, when raising the" + " AfterMessage event (including the details of the first error), this exception occurred: {1}", logicalMessageExceptionOrNull, exceptionWhileRaisingEvent); } else { log.Error("An exception occurred while raising the AfterMessage event: {0}", exceptionWhileRaisingEvent); } } context.ClearLogicalMessage(); } } foreach (var unitOfWork in unitsOfWork) { try { unitOfWork.Commit(); } catch (Exception exception) { throw new UnitOfWorkCommitException(exception, unitOfWork); } } } catch { foreach (var unitOfWork in unitsOfWork) { try { unitOfWork.Abort(); } catch (Exception abortException) { log.Warn("An error occurred while aborting the unit of work {0}: {1}", unitOfWork, abortException); } } throw; } finally { foreach (var unitOfWork in unitsOfWork) { unitOfWork.Dispose(); } } if (scope != null) { scope.Complete(); } } } catch (Exception exception) { transportMessageExceptionOrNull = exception; log.Debug("Handling message {0} with ID {1} has failed", label, id); errorTracker.TrackDeliveryFail(id, exception); throw new MessageHandleException(id, exception); } finally { try { AfterTransportMessage(transportMessageExceptionOrNull, transportMessage); } catch (Exception exceptionWhileRaisingEvent) { if (transportMessageExceptionOrNull != null) { log.Error( "An exception occurred while raising the AfterTransportMessage event, and an exception occurred some" + " time before that as well. The first exception was this: {0}. And then, when raising the" + " AfterTransportMessage event (including the details of the first error), this exception occurred: {1}", transportMessageExceptionOrNull, exceptionWhileRaisingEvent); } else { log.Error("An exception occurred while raising the AfterTransportMessage event: {0}", exceptionWhileRaisingEvent); } } if (context != null) { context.Dispose(); //< dispose it if we entered } } errorTracker.StopTracking(id); }
void TryProcessIncomingMessage() { using (var transactionScope = BeginTransaction()) { var transportMessage = receiveMessages.ReceiveMessage(); if (transportMessage == null) { Thread.Sleep(20); return; } var id = transportMessage.Id; var label = transportMessage.Label; MessageContext context = null; if (errorTracker.MessageHasFailedMaximumNumberOfTimes(id)) { log.Error("Handling message {0} has failed the maximum number of times", id); MessageFailedMaxNumberOfTimes(transportMessage, errorTracker.GetErrorText(id)); errorTracker.StopTracking(id); try { PoisonMessage(transportMessage); } catch (Exception exceptionWhileRaisingEvent) { log.Error("An exception occurred while raising the PoisonMessage event: {0}", exceptionWhileRaisingEvent); } } else { try { BeforeTransportMessage(transportMessage); var message = serializeMessages.Deserialize(transportMessage); // successfully deserialized the transport message, let's enter a message context context = MessageContext.Enter(message.Headers); foreach (var logicalMessage in message.Messages) { context.SetLogicalMessage(logicalMessage); try { BeforeMessage(logicalMessage); var typeToDispatch = logicalMessage.GetType(); log.Debug("Dispatching message {0}: {1}", id, typeToDispatch); GetDispatchMethod(typeToDispatch).Invoke(this, new[] { logicalMessage }); AfterMessage(null, logicalMessage); } catch (Exception exception) { try { AfterMessage(exception, logicalMessage); } catch (Exception exceptionWhileRaisingEvent) { log.Error("An exception occurred while raising the AfterMessage event, and an exception occurred some time before that as well. The first exception was this: {0}. And then, when raising the AfterMessage event (including the details of the first error), this exception occurred: {1}", exception, exceptionWhileRaisingEvent); } throw; } finally { context.ClearLogicalMessage(); } } AfterTransportMessage(null, transportMessage); } catch (Exception exception) { log.Debug("Handling message {0} ({1}) has failed", label, id); try { AfterTransportMessage(exception, transportMessage); } catch (Exception exceptionWhileRaisingEvent) { log.Error("An exception occurred while raising the AfterTransportMessage event, and an exception occurred some time before that as well. The first exception was this: {0}. And then, when raising the AfterTransportMessage event (including the details of the first error), this exception occurred: {1}", exception, exceptionWhileRaisingEvent); } errorTracker.TrackDeliveryFail(id, exception); if (context != null) { context.Dispose(); //< dispose it if we entered } throw; } } transactionScope.Complete(); if (context != null) { context.Dispose(); //< dispose it if we entered } errorTracker.StopTracking(id); } }
void DoTry() { var transportMessage = receiveMessages.ReceiveMessage(TransactionContext.Current); if (transportMessage == null) { // to back off and relax then there's no messages to process, we do this successiveNullMessagesReceived++; var sleepTimeIndex = Math.Min(nullMessageSleepTimes.Length - 1, successiveNullMessagesReceived); var timeToSleep = nullMessageSleepTimes[sleepTimeIndex]; Thread.Sleep(timeToSleep); return; } successiveNullMessagesReceived = 0; var id = transportMessage.Id; var label = transportMessage.Label; MessageContext context = null; if (id == null) { HandlePoisonMessage(id, transportMessage); return; } if (errorTracker.MessageHasFailedMaximumNumberOfTimes(id)) { HandlePoisonMessage(id, transportMessage); errorTracker.StopTracking(id); return; } Exception transportMessageExceptionOrNull = null; try { BeforeTransportMessage(transportMessage); using (var scope = BeginTransaction()) { var message = serializeMessages.Deserialize(transportMessage); // successfully deserialized the transport message, let's enter a message context context = MessageContext.Establish(message.Headers); MessageContextEstablished(context); var unitsOfWork = unitOfWorkManagers.Select(u => u.Create()) .Where(u => !ReferenceEquals(null, u)) .ToArray(); //< remember to invoke the chain here :) try { foreach (var logicalMessage in message.Messages.Select(MutateIncoming)) { context.SetLogicalMessage(logicalMessage); Exception logicalMessageExceptionOrNull = null; try { BeforeMessage(logicalMessage); var typeToDispatch = logicalMessage.GetType(); log.Debug("Dispatching message {0}: {1}", id, typeToDispatch); GetDispatchMethod(typeToDispatch) .Invoke(this, new[] { logicalMessage }); } catch (Exception exception) { logicalMessageExceptionOrNull = exception; throw; } finally { try { AfterMessage(logicalMessageExceptionOrNull, logicalMessage); } catch (Exception exceptionWhileRaisingEvent) { if (logicalMessageExceptionOrNull != null) { log.Error( "An exception occurred while raising the AfterMessage event, and an exception occurred some" + " time before that as well. The first exception was this: {0}. And then, when raising the" + " AfterMessage event (including the details of the first error), this exception occurred: {1}", logicalMessageExceptionOrNull, exceptionWhileRaisingEvent); } else { log.Error("An exception occurred while raising the AfterMessage event: {0}", exceptionWhileRaisingEvent); } } context.ClearLogicalMessage(); } } foreach (var unitOfWork in unitsOfWork) { unitOfWork.Commit(); } } catch { foreach (var unitOfWork in unitsOfWork) { try { unitOfWork.Abort(); } catch (Exception abortException) { log.Warn("An error occurred while aborting the unit of work {0}: {1}", unitOfWork, abortException); } } throw; } finally { foreach (var unitOfWork in unitsOfWork) { unitOfWork.Dispose(); } } if (scope != null) { scope.Complete(); } } } catch (Exception exception) { transportMessageExceptionOrNull = exception; log.Debug("Handling message {0} ({1}) has failed", label, id); errorTracker.TrackDeliveryFail(id, exception); throw; } finally { try { AfterTransportMessage(transportMessageExceptionOrNull, transportMessage); } catch (Exception exceptionWhileRaisingEvent) { if (transportMessageExceptionOrNull != null) { log.Error( "An exception occurred while raising the AfterTransportMessage event, and an exception occurred some" + " time before that as well. The first exception was this: {0}. And then, when raising the" + " AfterTransportMessage event (including the details of the first error), this exception occurred: {1}", transportMessageExceptionOrNull, exceptionWhileRaisingEvent); } else { log.Error("An exception occurred while raising the AfterTransportMessage event: {0}", exceptionWhileRaisingEvent); } } if (context != null) { context.Dispose(); //< dispose it if we entered } } errorTracker.StopTracking(id); }