Ejemplo n.º 1
0
        /// <summary>
        /// Acquires an ackable channel from the channel pool, then publishes message based on the letter/envelope parameters and waits for confirmation.
        /// <para>Only throws exception when failing to acquire channel or when creating a receipt after the ReceiptBuffer is closed.</para>
        /// <para>Not fully ready for production yet.</para>
        /// </summary>
        /// <param name="message"></param>
        /// <param name="createReceipt"></param>
        /// <param name="withOptionalHeaders"></param>
        public async Task PublishWithConfirmationAsync(IMessage message, bool createReceipt, bool withOptionalHeaders = true)
        {
            var error    = false;
            var chanHost = await _channelPool
                           .GetAckChannelAsync()
                           .ConfigureAwait(false);

            try
            {
                chanHost.GetChannel().WaitForConfirmsOrDie(_waitForConfirmation);

                chanHost
                .GetChannel()
                .BasicPublish(
                    message.Envelope.Exchange,
                    message.Envelope.RoutingKey,
                    message.Envelope.RoutingOptions?.Mandatory ?? false,
                    message.BuildProperties(chanHost, withOptionalHeaders),
                    message.GetBodyToPublish(_serializationProvider));

                chanHost.GetChannel().WaitForConfirmsOrDie(_waitForConfirmation);
            }
            catch (Exception ex)
            {
                _logger.LogDebug(
                    LogMessages.Publishers.PublishMessageFailed,
                    $"{message.Envelope.Exchange}->{message.Envelope.RoutingKey}",
                    message.MessageId,
                    ex.Message);

                error = true;
            }
            finally
            {
                if (createReceipt)
                {
                    await CreateReceiptAsync(message, error)
                    .ConfigureAwait(false);
                }

                await _channelPool
                .ReturnChannelAsync(chanHost, error);
            }
        }