Example #1
0
 private void HandleAckException(Exception exception, string message, ulong deliveryTag, IModel channel, MessageHeaders messageHeaders)
 {
     try
     {
         _eventBusConfiguration.Logger.LogCritical(exception.ToString());
         ResiliencePolicies.GeneralRetryPolicyFactory(_eventBusConfiguration.Logger)
         .Execute(GetAckOnExceptionAction(message, deliveryTag, exception, channel, messageHeaders));
     }
     catch (Exception ex)
     {
         _eventBusConfiguration.Logger.LogCritical(ex.ToString());
     }
 }
Example #2
0
        private IModel CreateConsumerChannel(string eventName)
        {
            if (!_connection.IsConnected)
            {
                _connection.TryConnect(ResiliencePolicies.ConnectionPolicyFactory);
            }

            var channel = _connection.CreateModel();

            var args = ResolveQueueArgs(channel, eventName);

            channel.ExchangeDeclare(ExchangeName, _queueConfiguration.ExchangeType.ToString().ToLower(), _queueConfiguration.DurableExchange);
            channel.QueueDeclare(_queueConfiguration.QueueName, _queueConfiguration.DurableQueue, false, false, args);
            channel.BasicQos(0, _queueConfiguration.PrefetchCount, false);

            var consumer = new EventingBasicConsumer(channel);

            var token = _eventCancellationTokenPool.GetCancellationToken(eventName);

            consumer.Received += (model, ea) =>
            {
                Task.Run(async() =>
                {
                    string message = string.Empty;
                    try
                    {
                        var localEventName = ea.RoutingKey;

                        using (var stream = new MemoryStream(ea.Body))
                            using (var reader = new StreamReader(stream))
                            {
                                message = reader.ReadToEnd();
                            }

                        if (token.IsCancellationRequested)
                        {
                            ResiliencePolicies.GeneralRetryPolicyFactory(_eventBusConfiguration.Logger)
                            .Execute(() => channel.BasicNack(ea.DeliveryTag, false, true));
                            return;
                        }

                        await HandleEvent(localEventName, message);
                        ResiliencePolicies.GeneralRetryPolicyFactory(_eventBusConfiguration.Logger)
                        .Execute(() => channel.BasicAck(ea.DeliveryTag, false));
                    }
                    catch (Exception ex)
                    {
                        HandleAckException(ex, message, ea.DeliveryTag, channel, new MessageHeaders(ea.BasicProperties.Headers));
                    }
                }, token);
            };

            channel.QueueBind(
                queue: _queueConfiguration.QueueName,
                exchange: ExchangeName,
                routingKey: eventName
                );

            channel.BasicConsume(queue: _queueConfiguration.QueueName,
                                 autoAck: false,
                                 consumer: consumer);

            channel.CallbackException += (sender, ea) =>
            {
                if (ea.Exception != null)
                {
                    _eventBusConfiguration.Logger.LogWarning(ea.Exception.ToString());
                }

                _consumerChannel.Dispose();
                _consumerChannel = CreateConsumerChannel(eventName);
            };

            return(channel);
        }