public ConsumerInstancePoolMessageProcessor(ConsumerSettings consumerSettings, MessageBusBase messageBus, Func <TMessage, byte[]> messagePayloadProvider, Action <TMessage, ConsumerContext> consumerContextInitializer = null)
        {
            if (messageBus is null)
            {
                throw new ArgumentNullException(nameof(messageBus));
            }

            _logger                 = messageBus.LoggerFactory.CreateLogger <ConsumerInstancePoolMessageProcessor <TMessage> >();
            _consumerSettings       = consumerSettings ?? throw new ArgumentNullException(nameof(consumerSettings));
            _messageBus             = messageBus ?? throw new ArgumentNullException(nameof(messageBus));
            _messagePayloadProvider = messagePayloadProvider ?? throw new ArgumentNullException(nameof(messagePayloadProvider));

            _consumerContextInitializer = consumerContextInitializer;
            _consumerWithContext        = typeof(IConsumerContextAware).IsAssignableFrom(consumerSettings.ConsumerType);

            _instancesQueue = new BufferBlock <object>();
            _instances      = ResolveInstances(consumerSettings);
            _instances.ForEach(x => _instancesQueue.Post(x));
        }
Пример #2
0
 public ResponseMessageProcessor(RequestResponseSettings requestResponseSettings, MessageBusBase messageBus, Func <TMessage, byte[]> messagePayloadProvider)
 {
     _requestResponseSettings = requestResponseSettings ?? throw new ArgumentNullException(nameof(requestResponseSettings));
     _messageBus             = messageBus ?? throw new ArgumentNullException(nameof(messageBus));
     _messagePayloadProvider = messagePayloadProvider ?? throw new ArgumentNullException(nameof(messagePayloadProvider));
 }
        public virtual async Task <Exception> ProcessMessage(TMessage msg)
        {
            Exception exceptionResult = null;

            try
            {
                DeserializeMessage(msg, out var requestMessage, out var requestId, out var expires, out var message);

                // Verify if the request/message is already expired
                if (expires != null)
                {
                    var currentTime = _messageBus.CurrentTime;
                    if (currentTime > expires.Value)
                    {
                        _logger.LogWarning("The message arrived too late and is already expired (expires {0}, current {1})", expires.Value, currentTime);

                        try
                        {
                            // Execute the event hook
                            _consumerSettings.OnMessageExpired?.Invoke(_messageBus, _consumerSettings, message, msg);
                            _messageBus.Settings.OnMessageExpired?.Invoke(_messageBus, _consumerSettings, message, msg);
                        }
                        catch (Exception eh)
                        {
                            MessageBusBase.HookFailed(_logger, eh, nameof(IConsumerEvents.OnMessageExpired));
                        }

                        // Do not process the expired message
                        return(null);
                    }
                }

                object response      = null;
                string responseError = null;

                var consumerInstance = await _instancesQueue.ReceiveAsync(_messageBus.CancellationToken).ConfigureAwait(false);

                try
                {
                    if (_consumerWithContext && _consumerContextInitializer != null)
                    {
                        var consumerContext = new ConsumerContext();
                        _consumerContextInitializer(msg, consumerContext);

                        var consumerWithContext = (IConsumerContextAware)consumerInstance;
                        consumerWithContext.Context.Value = consumerContext;
                    }

                    try
                    {
                        // Execute the event hook
                        _consumerSettings.OnMessageArrived?.Invoke(_messageBus, _consumerSettings, message, _consumerSettings.Topic, msg);
                        _messageBus.Settings.OnMessageArrived?.Invoke(_messageBus, _consumerSettings, message, _consumerSettings.Topic, msg);
                    }
                    catch (Exception eh)
                    {
                        MessageBusBase.HookFailed(_logger, eh, nameof(IConsumerEvents.OnMessageArrived));
                    }

                    // the consumer just subscribes to the message
                    var task = _consumerSettings.ConsumerMethod(consumerInstance, message, _consumerSettings.Topic);
                    await task.ConfigureAwait(false);

                    if (_consumerSettings.ConsumerMode == ConsumerMode.RequestResponse)
                    {
                        // the consumer handles the request (and replies)
                        response = _consumerSettings.ConsumerMethodResult(task);
                    }
                }
                catch (Exception e)
                {
                    if (_consumerSettings.ConsumerMode == ConsumerMode.RequestResponse)
                    {
                        _logger.LogError(e, "Handler execution failed");
                        // Save the exception
                        responseError = e.ToString();
                    }
                    else
                    {
                        _logger.LogError(e, "Consumer execution failed");
                    }

                    try
                    {
                        // Execute the event hook
                        _consumerSettings.OnMessageFault?.Invoke(_messageBus, _consumerSettings, message, e, msg);
                        _messageBus.Settings.OnMessageFault?.Invoke(_messageBus, _consumerSettings, message, e, msg);
                    }
                    catch (Exception eh)
                    {
                        MessageBusBase.HookFailed(_logger, eh, nameof(IConsumerEvents.OnMessageFault));
                    }

                    exceptionResult = e;
                }
                finally
                {
                    await _instancesQueue.SendAsync(consumerInstance).ConfigureAwait(false);
                }

                if (response != null || responseError != null)
                {
                    // send the response (or error response)
                    _logger.LogDebug("Serializing the response {0} of type {1} for RequestId: {2}...", response, _consumerSettings.ResponseType, requestId);

                    var responseMessage = new MessageWithHeaders();
                    responseMessage.SetHeader(ReqRespMessageHeaders.RequestId, requestId);
                    responseMessage.SetHeader(ReqRespMessageHeaders.Error, responseError);

                    await _messageBus.ProduceResponse(message, requestMessage, response, responseMessage, _consumerSettings).ConfigureAwait(false);
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Processing of the message {0} of type {1} failed", msg, _consumerSettings.MessageType);
                exceptionResult = e;
            }
            return(exceptionResult);
        }
 public ResponseMessageProcessor(RequestResponseSettings requestResponseSettings, MessageBusBase messageBus, Func <TMessage, byte[]> messagePayloadProvider)
 {
     _requestResponseSettings = requestResponseSettings;
     _messageBus             = messageBus;
     _messagePayloadProvider = messagePayloadProvider;
 }