Exemple #1
0
        // -------------------------------- publish ---------------------------------------------

        public void Publish(
            IExchange exchange,
            string routingKey,
            bool mandatory,
            bool immediate,
            MessageProperties messageProperties,
            byte[] body)
        {
            // Fix me: It's very hard now to move publish logic to separate abstraction, just leave it here.
            var rawMessage = produceConsumeInterceptor.OnProduce(new RawMessage(messageProperties, body));

            if (connectionConfiguration.PublisherConfirms)
            {
                var timeBudget = new TimeBudget(TimeSpan.FromSeconds(connectionConfiguration.Timeout)).Start();
                while (!timeBudget.IsExpired())
                {
                    var confirmsWaiter = clientCommandDispatcher.Invoke(model =>
                    {
                        var properties = model.CreateBasicProperties();
                        rawMessage.Properties.CopyTo(properties);

                        var waiter = confirmationListener.GetWaiter(model);

                        try
                        {
                            model.BasicPublish(exchange.Name, routingKey, mandatory, immediate, properties, rawMessage.Body);
                        }
                        catch (Exception)
                        {
                            waiter.Cancel();
                            throw;
                        }

                        return(waiter);
                    });

                    try
                    {
                        confirmsWaiter.Wait(timeBudget.GetRemainingTime());
                        break;
                    }
                    catch (PublishInterruptedException)
                    {
                    }
                }
            }
            else
            {
                clientCommandDispatcher.Invoke(model =>
                {
                    var properties = model.CreateBasicProperties();
                    rawMessage.Properties.CopyTo(properties);
                    model.BasicPublish(exchange.Name, routingKey, mandatory, immediate, properties, rawMessage.Body);
                });
            }
            eventBus.Publish(new PublishedMessageEvent(exchange.Name, routingKey, rawMessage.Properties, rawMessage.Body));
            logger.DebugWrite("Published to exchange: '{0}', routing key: '{1}', correlationId: '{2}'", exchange.Name, routingKey, messageProperties.CorrelationId);
        }
        // -------------------------------- publish ---------------------------------------------

        public virtual Task PublishAsync(
            IExchange exchange,
            string routingKey,
            bool mandatory,
            bool immediate,
            MessageProperties messageProperties,
            byte[] body)
        {
            Preconditions.CheckNotNull(exchange, "exchange");
            Preconditions.CheckShortString(routingKey, "routingKey");
            Preconditions.CheckNotNull(messageProperties, "messageProperties");
            Preconditions.CheckNotNull(body, "body");

            var rawMessage = produceConsumeInterceptor.OnProduce(new RawMessage(messageProperties, body));

            return(clientCommandDispatcher.Invoke(x =>
            {
                var properties = x.CreateBasicProperties();
                rawMessage.Properties.CopyTo(properties);

                return publisher.Publish(x, m => m.BasicPublish(exchange.Name, routingKey, mandatory, immediate, properties, rawMessage.Body))
                .Then(() =>
                {
                    eventBus.Publish(new PublishedMessageEvent(exchange.Name, routingKey, rawMessage.Properties, rawMessage.Body));
                    logger.DebugWrite("Published to exchange: '{0}', routing key: '{1}', correlationId: '{2}'", exchange.Name, routingKey, messageProperties.CorrelationId);
                });
            }).Unwrap());
        }
Exemple #3
0
        /// <inheritdoc />
        public virtual async Task PublishAsync(
            IExchange exchange,
            string routingKey,
            bool mandatory,
            MessageProperties messageProperties,
            byte[] body,
            CancellationToken cancellationToken
            )
        {
            Preconditions.CheckNotNull(exchange, "exchange");
            Preconditions.CheckShortString(routingKey, "routingKey");
            Preconditions.CheckNotNull(messageProperties, "messageProperties");
            Preconditions.CheckNotNull(body, "body");

            using var cts = cancellationToken.WithTimeout(configuration.Timeout);

            var rawMessage = produceConsumeInterceptor.OnProduce(new ProducedMessage(messageProperties, body));

            if (configuration.PublisherConfirms)
            {
                while (true)
                {
                    var pendingConfirmation = await clientCommandDispatcher.InvokeAsync(model =>
                    {
                        var confirmation = confirmationListener.CreatePendingConfirmation(model);
                        rawMessage.Properties.SetConfirmationId(confirmation.Id);
                        var properties = model.CreateBasicProperties();
                        rawMessage.Properties.CopyTo(properties);
                        try
                        {
                            model.BasicPublish(exchange.Name, routingKey, mandatory, properties, rawMessage.Body);
                        }
                        catch (Exception)
                        {
                            confirmation.Cancel();
                            throw;
                        }
                        return(confirmation);
                    }, ChannelDispatchOptions.PublishWithConfirms, cts.Token).ConfigureAwait(false);

                    try
                    {
                        await pendingConfirmation.WaitAsync(cts.Token).ConfigureAwait(false);

                        break;
                    }
                    catch (PublishInterruptedException)
                    {
                    }
                }
            }
            else
            {
                await clientCommandDispatcher.InvokeAsync(model =>
                {
                    var properties = model.CreateBasicProperties();
                    rawMessage.Properties.CopyTo(properties);
                    model.BasicPublish(exchange.Name, routingKey, mandatory, properties, rawMessage.Body);
                }, ChannelDispatchOptions.Publish, cts.Token).ConfigureAwait(false);
            }

            eventBus.Publish(new PublishedMessageEvent(exchange.Name, routingKey, rawMessage.Properties, rawMessage.Body));

            if (logger.IsDebugEnabled())
            {
                logger.DebugFormat(
                    "Published to exchange {exchange} with routingKey={routingKey} and correlationId={correlationId}",
                    exchange.Name,
                    routingKey,
                    messageProperties.CorrelationId
                    );
            }
        }
        // -------------------------------- publish ---------------------------------------------
        public void Publish(
            IExchange exchange,
            string routingKey,
            bool mandatory,
            MessageProperties messageProperties,
            byte[] body)
        {
            // Fix me: It's very hard now to move publish logic to separate abstraction, just leave it here.
            var rawMessage = produceConsumeInterceptor.OnProduce(new RawMessage(messageProperties, body));

            if (connectionConfiguration.PublisherConfirms)
            {
                var timeout = TimeBudget.Start(connectionConfiguration.GetTimeout());
                while (true)
                {
                    if (timeout.IsExpired())
                    {
                        throw new TimeoutException($"Publish timed out after {connectionConfiguration.Timeout} seconds");
                    }

                    var confirmsWaiter = clientCommandDispatcher.Invoke(model =>
                    {
                        var properties = model.CreateBasicProperties();
                        rawMessage.Properties.CopyTo(properties);

                        var waiter = confirmationListener.GetWaiter(model);

                        try
                        {
                            model.BasicPublish(exchange.Name, routingKey, mandatory, properties, rawMessage.Body);
                        }
                        catch (Exception)
                        {
                            waiter.Cancel();
                            throw;
                        }

                        return(waiter);
                    });

                    try
                    {
                        confirmsWaiter.Wait(timeout);
                        break;
                    }
                    catch (PublishInterruptedException)
                    {
                    }
                }
            }
            else
            {
                clientCommandDispatcher.Invoke(model =>
                {
                    var properties = model.CreateBasicProperties();
                    rawMessage.Properties.CopyTo(properties);
                    model.BasicPublish(exchange.Name, routingKey, mandatory, properties, rawMessage.Body);
                });
            }
            eventBus.Publish(new PublishedMessageEvent(exchange.Name, routingKey, rawMessage.Properties, rawMessage.Body));

            if (logger.IsDebugEnabled())
            {
                logger.DebugFormat(
                    "Published to exchange {exchange} with routingKey={routingKey} and correlationId={correlationId}",
                    exchange.Name,
                    routingKey,
                    messageProperties.CorrelationId
                    );
            }
        }