/// <summary> /// Process the given message /// </summary> /// <param name="message">Transport message to be dispatched to the event handlers</param> /// <param name="busInstance">Instance of the send bus to inject into the event handlers</param> /// <returns>True is all event handlers processed successfully</returns> public MessageProcessingResult ProcessMessage(TransportMessage message, IBus busInstance) { if (message == null) { throw new ArgumentNullException("message"); } MessageProcessingResult result = new MessageProcessingResult(); Stopwatch watch = new Stopwatch(); watch.Start(); if (_handlerTypes.ContainsKey(message.MessageType)) { Log.TraceFormat("Processing {0} handlers for message type {1}", _handlerTypes[message.MessageType].Count, message.MessageTypeName); var handlerMethod = typeof(IHandleMessage <>).MakeGenericType(message.MessageType).GetMethod("Handle"); using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required)) { foreach (Type handlerType in _handlerTypes[message.MessageType]) { using (IObjectBuilder childBuilder = _objectBuilder.GetNestedBuilder()) { if (busInstance != null) { childBuilder.RegisterInstance <IBus>(busInstance); } childBuilder.RegisterInstance(LogManager.GetLogger(handlerType)); Log.TraceFormat("Running handler {0}", handlerType.Name); try { var handler = childBuilder.GetValue(handlerType); handlerMethod.Invoke(handler, new object[] { message.Message }); } catch (TargetInvocationException ex) { Log.ErrorFormat("Error in handling {0} with {1}", ex, message.MessageType.Name, handlerType.Name); result.Exception = ex.InnerException ?? ex; } catch (Exception ex) { Log.ErrorFormat("Error in handling {0} with {1}", ex, message.MessageType.Name, handlerType.Name); result.Exception = ex; } } } result.WasSuccessful = result.Exception == null; if (result.WasSuccessful) { transactionScope.Complete(); } } } else { Log.WarnFormat("Could not find a handler for {0}", message.MessageTypeName); result.Exception = new Exception(string.Format("Could not find a handler for {0}", message.MessageTypeName)); } watch.Stop(); result.Runtime = watch.Elapsed; return(result); }
/// <summary> /// Starts the loop for polling the SQS queue /// </summary> public async void Run() { Log.InfoFormat("[{0}] Starting message pump", Id); while (!_cancellationToken.IsCancellationRequested) { Log.TraceFormat("[{0}] Starting receiving call", Id); try { IEnumerable <TransportMessage> recievedMessages = await _queue.GetMessages(_cancellationToken.Token); Log.TraceFormat("[{1}] Received {0} messages", recievedMessages.Count(), Id); foreach (TransportMessage message in recievedMessages) { Log.InfoFormat("[{1}] Received message of type '{0}'", message.MessageTypeName, Id); _messageLogger.InboundLogMessage(message.Body, message.MessageTypeName, message.Id, message.AttemptNumber); MessageProcessingResult result; if (message.MessageParsingSucceeded) { Log.TraceFormat("[{0}] Processing message", Id); result = _messageProcessor.ProcessMessage(message, _bus); Log.TraceFormat("[{0}] Processed message - Error: {1}", Id, !result.WasSuccessful); } else { Log.ErrorFormat("[{1}] Failed to parse message of type {0}", message.Exception, message.MessageTypeName, Id); result = new MessageProcessingResult() { WasSuccessful = false, Exception = new Exception("Message parse failure") }; } if (result.WasSuccessful) { Log.InfoFormat("[{0}] Removing message from the queue", Id); _queue.RemoveMessage(message); } else if (message.AttemptNumber == _messageRetryCount) { Log.InfoFormat("[{0}] Message faulted ", Id); _messageProcessor.ProcessFaultedMessage(message, _bus, result.Exception); } MessageStatistics stats = new MessageStatistics() { FinalAttempt = message.AttemptNumber == _messageRetryCount, HandlerRunTime = result.Runtime, MessageLength = message.Body.Length, MessageType = message.MessageTypeName, Success = result.WasSuccessful, PreviousRetryCount = message.AttemptNumber, }; _messageProcessor.ProcessMessageStatistics(stats); } } catch (OperationCanceledException) { } catch (Exception ex) { Log.ErrorFormat("[{0}] Error occurred in message pump run", ex, Id); } } }