protected void DeserializeMessage(TMessage msg, out MessageWithHeaders requestMessage, out string requestId, out DateTimeOffset?expires, out object message)
        {
            var msgPayload = _messagePayloadProvider(msg);

            requestMessage = null;
            requestId      = null;
            expires        = null;

            _logger.LogDebug("Deserializing message...");

            message = _consumerSettings.IsRequestMessage
                ? _messageBus.DeserializeRequest(_consumerSettings.MessageType, msgPayload, out requestMessage)
                : _messageBus.Settings.Serializer.Deserialize(_consumerSettings.MessageType, msgPayload);

            if (requestMessage != null)
            {
                requestMessage.TryGetHeader(ReqRespMessageHeaders.RequestId, out requestId);
                requestMessage.TryGetHeader(ReqRespMessageHeaders.Expires, out expires);
            }
        }
        public virtual async Task ProcessMessage(TMessage msg)
        {
            var msgPayload = _messagePayloadProvider(msg);

            MessageWithHeaders requestMessage = null;
            string             requestId      = null;
            DateTimeOffset?    expires        = null;

            _log.Debug("Deserializing message...");
            var message = _consumerSettings.IsRequestMessage
                ? _messageBus.DeserializeRequest(_consumerSettings.MessageType, msgPayload, out requestMessage)
                : _messageBus.Settings.Serializer.Deserialize(_consumerSettings.MessageType, msgPayload);

            if (requestMessage != null)
            {
                requestMessage.TryGetHeader(ReqRespMessageHeaders.RequestId, out requestId);
                requestMessage.TryGetHeader(ReqRespMessageHeaders.Expires, out expires);
            }

            // Verify if the request/message is already expired
            if (expires.HasValue)
            {
                var currentTime = _messageBus.CurrentTime;
                if (currentTime > expires.Value)
                {
                    _log.WarnFormat(CultureInfo.InvariantCulture, "The message arrived too late and is already expired (expires {0}, current {1})", expires.Value, currentTime);

                    try
                    {
                        // Execute the event hook
                        (_consumerSettings.OnMessageExpired ?? _messageBus.Settings.OnMessageExpired)?.Invoke(_consumerSettings, message);
                    }
                    catch (Exception eh)
                    {
                        // When the hook itself error out, catch the exception
                        _log.ErrorFormat(CultureInfo.InvariantCulture, "{0} method failed", eh, nameof(IConsumerEvents.OnMessageExpired));
                    }

                    // Do not process the expired message
                    return;
                }
            }

            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;
                }

                // the consumer just subscribes to the message
                var task = _consumerRuntimeInfo.OnHandle(consumerInstance, message);
                await task.ConfigureAwait(false);

                if (_consumerSettings.ConsumerMode == ConsumerMode.RequestResponse)
                {
                    // the consumer handles the request (and replies)
                    response = _consumerRuntimeInfo.GetResponseValue(task);
                }
            }
            catch (Exception e)
            {
                if (_consumerSettings.ConsumerMode == ConsumerMode.RequestResponse)
                {
                    _log.ErrorFormat(CultureInfo.InvariantCulture, "Handler execution failed", e);
                    // Save the exception
                    responseError = e.ToString();
                }
                else
                {
                    _log.ErrorFormat(CultureInfo.InvariantCulture, "Consumer execution failed", e);
                }

                try
                {
                    // Execute the event hook
                    (_consumerSettings.OnMessageFault ?? _messageBus.Settings.OnMessageFault)?.Invoke(_consumerSettings, message, e);
                }
                catch (Exception eh)
                {
                    // When the hook itself error out, catch the exception
                    _log.ErrorFormat(CultureInfo.InvariantCulture, "{0} method failed", eh, nameof(IConsumerEvents.OnMessageFault));
                }
            }
            finally
            {
                await _instancesQueue.SendAsync(consumerInstance).ConfigureAwait(false);
            }

            if (response != null || responseError != null)
            {
                // send the response (or error response)
                _log.DebugFormat(CultureInfo.InvariantCulture, "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);
            }
        }
예제 #3
0
        public virtual async Task ProcessMessage(TMessage msg)
        {
            var msgPayload = _messagePayloadProvider(msg);

            string         requestId = null, replyTo = null;
            DateTimeOffset?expires = null;

            Log.Debug("Deserializing message...");
            var message = _consumerSettings.IsRequestMessage
                ? _messageBus.DeserializeRequest(_consumerSettings.MessageType, msgPayload, out requestId, out replyTo, out expires)
                : _messageBus.Settings.Serializer.Deserialize(_consumerSettings.MessageType, msgPayload);

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

                    // Execute the event hook
                    (_consumerSettings.OnMessageExpired ?? _messageBus.Settings.OnMessageExpired)?.Invoke(_consumerSettings, message);

                    // Do not process the expired message
                    return;
                }
            }

            object response      = null;
            string responseError = null;

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

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

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

                // the consumer just subscribes to the message
                var   task = (Task)_consumerOnHandleMethod.Invoke(consumerInstance, new[] { message, _consumerSettings.Topic });
                await task;

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

                try
                {
                    // Execute the event hook
                    (_consumerSettings.OnMessageFault ?? _messageBus.Settings.OnMessageFault)?.Invoke(_consumerSettings, message, e);
                }
                catch (Exception eh)
                {
                    // When the hook itself error out, catch the exception
                    Log.ErrorFormat("{0} method failed", eh, nameof(IConsumerEvents.OnMessageFault));
                }
            }
            finally
            {
                await _instancesQueue.SendAsync(consumerInstance);
            }

            if (response != null || responseError != null)
            {
                // send the response (or error response)
                Log.Debug("Serializing the response...");
                var responsePayload = _messageBus.SerializeResponse(_consumerSettings.ResponseType, response, requestId, responseError);
                await _messageBus.PublishToTransport(_consumerSettings.ResponseType, response, replyTo, responsePayload);
            }
        }