public void OnMessage(IMessage message, RC.IModel channel) { try { MessageListener.OnMessage(message, channel); } finally { Latch.Signal(); } }
/// <summary> /// Invoke the specified listener as Spring SessionAwareMessageListener, /// exposing a new Rabbit Channel (potentially with its own transaction) /// to the listener if demanded. /// </summary> /// <param name="listener">The Spring ISessionAwareMessageListener to invoke.</param> /// <param name="channel">The channel to operate on.</param> /// <param name="message">The received message.</param> /// <see cref="IChannelAwareMessageListener"/> /// <see cref="ExposeListenerChannel"/> protected virtual void DoInvokeListener(IChannelAwareMessageListener listener, IModel channel, Message message) { RabbitResourceHolder resourceHolder = null; try { var channelToUse = channel; if (!this.ExposeListenerChannel) { //We need to expose a separate Channel. resourceHolder = GetTransactionalResourceHolder(); channelToUse = resourceHolder.Channel; } // Actually invoke the message listener try { listener.OnMessage(message, channelToUse); } catch (Exception e) { throw this.WrapToListenerExecutionFailedExceptionIfNeeded(e); } } finally { ConnectionFactoryUtils.ReleaseResources(resourceHolder); } }
/// <summary>Invoke the specified listener as Spring SessionAwareMessageListener, /// exposing a new Rabbit Channel (potentially with its own transaction) /// to the listener if demanded.</summary> /// <param name="listener">The Spring ISessionAwareMessageListener to invoke.</param> /// <param name="channel">The channel to operate on.</param> /// <param name="message">The received message.</param> /// <see cref="IChannelAwareMessageListener"/><see cref="ExposeListenerChannel"/> protected virtual void DoInvokeListener(IChannelAwareMessageListener listener, IModel channel, Message message) { RabbitResourceHolder resourceHolder = null; var channelToUse = channel; var boundHere = false; try { if (!this.ExposeListenerChannel) { // We need to expose a separate Channel. resourceHolder = this.GetTransactionalResourceHolder(); channelToUse = resourceHolder.Channel; if (this.IsChannelLocallyTransacted(channelToUse) && !TransactionSynchronizationManager.ActualTransactionActive) { resourceHolder.SynchronizedWithTransaction = true; TransactionSynchronizationManager.BindResource( this.ConnectionFactory, resourceHolder); boundHere = true; } } else { // if locally transacted, bind the current channel to make it available to RabbitTemplate if (this.IsChannelLocallyTransacted(channel)) { var localResourceHolder = new RabbitResourceHolder(channelToUse, false); localResourceHolder.SynchronizedWithTransaction = true; TransactionSynchronizationManager.BindResource(this.ConnectionFactory, localResourceHolder); boundHere = true; } } // Actually invoke the message listener try { listener.OnMessage(message, channelToUse); } catch (Exception e) { throw this.WrapToListenerExecutionFailedExceptionIfNeeded(e); } } finally { if (resourceHolder != null && boundHere) { // so the channel exposed (because exposeListenerChannel is false) will be closed resourceHolder.SynchronizedWithTransaction = false; } ConnectionFactoryUtils.ReleaseResources(resourceHolder); if (boundHere) { // unbind if we bound TransactionSynchronizationManager.UnbindResource(this.ConnectionFactory); if (!this.ExposeListenerChannel && this.IsChannelLocallyTransacted(channelToUse)) { /* * commit the temporary channel we exposed; the consumer's channel * will be committed later. Note that when exposing a different channel * when there's no transaction manager, the exposed channel is committed * on each message, and not based on txSize. */ RabbitUtils.CommitIfNecessary(channelToUse); } } } }
protected virtual void DoInvokeListener(IChannelAwareMessageListener listener, R.IModel channel, object data) { Message message = null; RabbitResourceHolder resourceHolder = null; var channelToUse = channel; var boundHere = false; try { if (!ExposeListenerChannel) { // We need to expose a separate Channel. resourceHolder = GetTransactionalResourceHolder(); channelToUse = resourceHolder.GetChannel(); /* * If there is a real transaction, the resource will have been bound; otherwise * we need to bind it temporarily here. Any work done on this channel * will be committed in the finally block. */ if (IsChannelLocallyTransacted && !TransactionSynchronizationManager.IsActualTransactionActive()) { resourceHolder.SynchronizedWithTransaction = true; TransactionSynchronizationManager.BindResource(ConnectionFactory, resourceHolder); boundHere = true; } } else { // if locally transacted, bind the current channel to make it available to RabbitTemplate if (IsChannelLocallyTransacted) { var localResourceHolder = new RabbitResourceHolder(channelToUse, false); localResourceHolder.SynchronizedWithTransaction = true; TransactionSynchronizationManager.BindResource(ConnectionFactory, localResourceHolder); boundHere = true; } } // Actually invoke the message listener... try { if (data is List <Message> asList) { listener.OnMessageBatch(asList, channelToUse); } else { message = (Message)data; listener.OnMessage(message, channelToUse); } } catch (Exception e) { _logger?.LogError("Exception in OnMessage call", e); throw WrapToListenerExecutionFailedExceptionIfNeeded(e, data); } } finally { CleanUpAfterInvoke(resourceHolder, channelToUse, boundHere); } }
/// <summary> /// Invoke the specified listener as Spring SessionAwareMessageListener, /// exposing a new Rabbit Channel (potentially with its own transaction) /// to the listener if demanded. /// </summary> /// <param name="listener">The Spring ISessionAwareMessageListener to invoke.</param> /// <param name="channel">The channel to operate on.</param> /// <param name="message">The received message.</param> /// <see cref="IChannelAwareMessageListener"/> /// <see cref="ExposeListenerChannel"/> protected virtual void DoInvokeListener(IChannelAwareMessageListener listener, IModel channel, Message message) { IConnection conToClose = null; IModel channelToClose = null; try { IModel channelToUse = channel; if (!ExposeListenerChannel) { //We need to expose a separate Session. conToClose = CreateConnection(); channelToClose = CreateChannel(conToClose); channelToUse = channelToClose; } // Actually invoke the message listener if (logger.IsDebugEnabled) { logger.Debug("Invoking listener with message of type [" + message.GetType() + "] and session [" + channelToUse + "]"); } listener.OnMessage(message, channelToUse); /* TODO need to figure out tx usage more // Clean up specially exposed Channel, if any if (channelToUse != channel) { if (channelToUse.Transacted && ChannelTransacted) { // Transacted session created by this container -> commit. Rabbit.CommitIfNecessary(channelToUse); } }*/ } finally { RabbitUtils.CloseChannel(channelToClose); RabbitUtils.CloseConnection(conToClose); } }