1

I'm new in RabbitMQ, and I using Publisher Confirm to ensure that message is delivered successfully.

But I'm facing a strange behavior, which is when I publish a message and take a sequenceNumber the function channel.BasicAcks is fired n times which n is the DeliveryTag, so if the DeliveryTag for this message is 5 the function channel.BasicAcks is fired 5 times?!!

And here is my code:

            IModel channel = _customRabbitMQ.GetChannel();
            IBasicProperties properties = _customRabbitMQ.GetBasicProperties();
            ulong sequenceNumber = channel.NextPublishSeqNo;

         
            message.SequenceNumber = sequenceNumber.ToString();
            _context.Messages.Update(message);
            await _context.SaveChangesAsync();

            try
            {
                _customRabbitMQ.AddOutstandingConfirm(sequenceNumber, message.Id);
                channel.BasicPublish(message.ExchangeName, message.RoutingKey, properties, Encoding.UTF8.GetBytes(JsonSerializer.Serialize(message)));
                Console.WriteLine("Message Published");
            }
            catch (Exception ex)
            {
                // TODO: log to custom logger here
                Console.WriteLine($"Error => {ex.Message}");
            }

            channel.BasicAcks += async (sender, ea) =>
            {
                try
                {
                    Console.WriteLine("Message Confirmed");

                    using var scope = _provider.CreateScope();
                    var _context = scope.ServiceProvider.GetService<Data.DataContext>();
                    var _customRabbitMQ = scope.ServiceProvider.GetService<CustomRabbitMQ>();

                    Guid messageId = _customRabbitMQ.GetOutstandingConfirm(ea.DeliveryTag);

                    Message message = await _context.Messages.Where(m => m.Id == messageId).FirstOrDefaultAsync();
                    message.Status = MessageStatuses.INQUEUE;
                    _context.Messages.Update(message);
                    await _context.SaveChangesAsync();

                    _customRabbitMQ.RemoveOutstandingConfirm(ea.DeliveryTag);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error => {ex.Message}");
                }
            };

            channel.BasicNacks += (sender, ea) =>
            {
                Console.WriteLine("Message Not Confirmed");
                _customRabbitMQ.RemoveOutstandingConfirm(ea.DeliveryTag);
            };
        }

So, why this happening and how to stop it and make it confirm only one time?

Thanks in advance.

Karim Alaa
  • 335
  • 2
  • 10
  • 34

0 Answers0