Ejemplo n.º 1
0
        protected override void Subscriber_Received(object sender, BasicDeliverEventArgs bdeArgs, IModel channel)
        {
            if (this.Process == null)
            {
                this._logger.LogWarning($"MessageWorker<{typeof(TInputMessage).FullName}> do not define Process() delegate. Bypass process message.");
                return;
            }

            if (bdeArgs == null)
            {
                this._logger.LogWarning($"Bypass message because BasicDeliverEventArgs is null.");
                return;
            }

            Interlocked.Increment(ref this._subscriber_received_count);

            var props = bdeArgs.BasicProperties;

            using (this._logger.BeginScope(new Dictionary <string, object>
            {
                [nameof(props.CorrelationId)] = props.CorrelationId
            }))
            {
                var           processOk = false;
                var           message   = string.Empty;
                TInputMessage input     = null;

                try
                {
                    message = Encoding.UTF8.GetString(bdeArgs.Body);

                    try
                    {
                        input = JsonConvert.DeserializeObject <TInputMessage>(message);
                        this._logger.LogInformation("ProcessMsg {@Input}", input);
                    }
                    catch
                    {
                        throw new Exception($"Deserialize to {typeof(TInputMessage).FullName} failed: " + message);
                    }

                    if (this._services == null)
                    {
                        this.Process(input, props.CorrelationId, null);
                    }
                    else
                    {
                        using (var scope = this._services.CreateScope())
                        {
                            TrackContext.TryToContext(scope.ServiceProvider, this.GetHeaders(props));
                            this.Process(input, props.CorrelationId, scope);
                        }
                    }

                    processOk = true;
                    this._logger.LogInformation("ProcessMsgOk");
                }
                catch (Exception ex)
                {
                    this._logger.LogError(ex, "ProcessMsgError");
                }

                try
                {
                    channel.BasicAck(
                        deliveryTag: bdeArgs.DeliveryTag,
                        multiple: false);
                    this._logger.LogInformation("AckMsgOk");

                    if (!processOk)
                    {
                        if (_messageKeeper != null)
                        {
                            _messageKeeper.Save(new MessageState
                            {
                                Meta = new MessageMeta
                                {
                                    RoutingKey    = bdeArgs.RoutingKey,
                                    CorrelationId = props.CorrelationId
                                },
                                Message = input ?? (object)message
                            });
                        }
                        this._logger.LogInformation("MsgDead");
                    }
                }
                catch (Exception ex)
                {
                    this._logger.LogError(ex, "AckMsgError");
                }
            }
            Interlocked.Decrement(ref this._subscriber_received_count);
            this._subscriber_received_wait.Set();
        }