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