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