void ProcessMessage(EnvelopeTransportContext context) { var processed = false; try { if (_memory.DoWeRemember(context.Unpacked.EnvelopeId)) { _observer.Notify(new EnvelopeDuplicateDiscarded(context.QueueName, context.Unpacked.EnvelopeId)); } else { _dispatcher.DispatchMessage(context.Unpacked); _memory.Memorize(context.Unpacked.EnvelopeId); } processed = true; } catch (Exception dispatchEx) { // if the code below fails, it will just cause everything to be reprocessed later, // which is OK (duplication manager will handle this) _observer.Notify(new EnvelopeDispatchFailed(context.Unpacked, context.QueueName, dispatchEx)); // quarantine is atomic with the processing if (_quarantine.TryToQuarantine(context, dispatchEx)) { _observer.Notify(new EnvelopeQuarantined(dispatchEx, context.Unpacked, context.QueueName)); // acking message is the last step! _inbox.AckMessage(context); } else { _inbox.TryNotifyNack(context); } } try { if (processed) { // 1st step - dequarantine, if present _quarantine.TryRelease(context); // 2nd step - ack. _inbox.AckMessage(context); // 3rd - notify. _observer.Notify(new EnvelopeAcked(context.QueueName, context.Unpacked.EnvelopeId, context.Unpacked.GetAllAttributes())); } } catch (Exception ex) { // not a big deal. Message will be processed again. _observer.Notify(new EnvelopeAckFailed(ex, context.Unpacked.EnvelopeId, context.QueueName)); } }
void ProcessMessage(MessageTransportContext context) { var dispatched = false; try { _dispatcher(context.Unpacked); dispatched = true; } catch (ThreadAbortException) { // we are shutting down. Stop immediately return; } catch (Exception dispatchEx) { // if the code below fails, it will just cause everything to be reprocessed later, // which is OK (duplication manager will handle this) SystemObserver.Notify(new MessageDispatchFailed(context, context.QueueName, dispatchEx)); // quarantine is atomic with the processing _inbox.TryNotifyNack(context); } if (!dispatched) { return; } try { _inbox.AckMessage(context); // 3rd - notify. SystemObserver.Notify(new MessageAcked(context)); } catch (ThreadAbortException) { // nothing. We are going to sleep } catch (Exception ex) { // not a big deal. Message will be processed again. SystemObserver.Notify(new MessageAckFailed(ex, context)); } }