private void PublishMessage(ProducerChannel channel, DatabaseMessage message)
        {
            string exchange = Settings.MessageBrokerSettings.TopicExchange;

            string routingKey = message.MessageType;

            byte[] messageBytes = Encoding.UTF8.GetBytes(message.MessageBody);

            ConfigureMessageProperties(message, channel.Properties);

            channel.Channel.BasicPublish(exchange, routingKey, channel.Properties, messageBytes);
        }
        private ulong CalculateDeliveryTagToWait(ProducerChannel producerChannel)
        {
            ulong deliveryTag = 0;

            foreach (Queue <DatabaseMessage> queue in producerChannel.Queues)
            {
                deliveryTag += (ulong)queue.Count;
            }

            deliveryTag += (producerChannel.Channel.NextPublishSeqNo - 1);

            return(deliveryTag);
        }
        private int PublishMessagesInBackground(object id)
        {
            int channelId = (int)id;

            ProducerChannel producerChannel = ProducerChannels[channelId];

            int messagesSent = 0;

            producerChannel.DeliveryTagToWait = CalculateDeliveryTagToWait(producerChannel);

            foreach (Queue <DatabaseMessage> queue in producerChannel.Queues)
            {
                while (queue.TryDequeue(out DatabaseMessage message))
                {
                    if (SendingCancellation.IsCancellationRequested)
                    {
                        return(0);
                    }

                    try
                    {
                        PublishMessage(producerChannel, message);
                        messagesSent++;
                    }
                    catch (Exception error)
                    {
                        ProducerExceptions.Enqueue(error);
                        SendingCancellation.Cancel();
                    }
                }
            }

            if (messagesSent > 0)
            {
                WaitForConfirms(producerChannel);
            }

            return(messagesSent);
        }
        private void WaitForConfirms(ProducerChannel channel)
        {
            try
            {
                int confirmationTimeout = Settings.MessageBrokerSettings.ConfirmationTimeout;

                if (confirmationTimeout < 600)
                {
                    confirmationTimeout = 600; // Добавлено для совместимости со старыми версиями
                }

                bool confirmed = channel.Channel.WaitForConfirms(TimeSpan.FromSeconds(confirmationTimeout), out bool timedout);

                if (!confirmed)
                {
                    ProducerExceptions.Enqueue(new OperationCanceledException(PUBLISHER_CONFIRMATION_ERROR_MESSAGE));
                    SendingCancellation.Cancel();
                }
                else if (timedout)
                {
                    ProducerExceptions.Enqueue(new OperationCanceledException(PUBLISHER_CONFIRMATION_TIMEOUT_MESSAGE));
                    SendingCancellation.Cancel();
                }
            }
            catch (OperationInterruptedException rabbitError)
            {
                ProducerExceptions.Enqueue(rabbitError);
                if (string.IsNullOrWhiteSpace(rabbitError.Message) || !rabbitError.Message.Contains("NOT_FOUND"))
                {
                    SendingCancellation.Cancel();
                }
            }
            catch (Exception error)
            {
                ProducerExceptions.Enqueue(error);
                SendingCancellation.Cancel();
            }
        }