Ejemplo n.º 1
0
        public virtual void Dispatch(MessageDispatch dispatch)
        {
            MessageListener listener        = this.listener;
            bool            dispatchMessage = false;

            try
            {
                lock (this.unconsumedMessages.SyncRoot)
                {
                    if (this.clearDispatchList)
                    {
                        // we are reconnecting so lets flush the in progress messages
                        this.clearDispatchList = false;
                        this.unconsumedMessages.Clear();

                        if (this.pendingAck != null && this.pendingAck.AckType == (byte)AckType.DeliveredAck)
                        {
                            // on resumption a pending delivered ack will be out of sync with
                            // re-deliveries.
                            if (Tracer.IsDebugEnabled)
                            {
                                Tracer.Debug("removing pending delivered ack on transport interupt: " + pendingAck);
                            }
                            this.pendingAck = null;
                        }
                    }

                    if (!this.unconsumedMessages.Closed)
                    {
                        if (listener != null && this.unconsumedMessages.Running)
                        {
                            dispatchMessage = true;
                        }
                        else
                        {
                            this.unconsumedMessages.Enqueue(dispatch);
                        }
                    }
                }

                if (dispatchMessage)
                {
                    ActiveMQMessage message = CreateActiveMQMessage(dispatch);

                    this.BeforeMessageIsConsumed(dispatch);

                    try
                    {
                        bool expired = (!IgnoreExpiration && message.IsExpired());

                        if (!expired)
                        {
                            listener(message);
                        }

                        this.AfterMessageIsConsumed(dispatch, expired);
                    }
                    catch (Exception e)
                    {
                        if (IsAutoAcknowledgeBatch || IsAutoAcknowledgeEach || IsIndividualAcknowledge)
                        {
                            // Redeliver the message
                            Rollback();
                        }
                        else
                        {
                            // Transacted or Client ack: Deliver the next message.
                            this.AfterMessageIsConsumed(dispatch, false);
                        }

                        Tracer.Error(this.info.ConsumerId + " Exception while processing message: " + e);

                        // If aborted we stop the abort here and let normal processing resume.
                        // This allows the session to shutdown normally and ack all messages
                        // that have outstanding acks in this consumer.
                        if ((Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == ThreadState.AbortRequested)
                        {
                            Thread.ResetAbort();
                        }
                    }
                }

                if (++dispatchedCount % 1000 == 0)
                {
                    dispatchedCount = 0;
                    Thread.Sleep(1);
                }
            }
            catch (Exception e)
            {
                this.session.Connection.OnSessionException(this.session, e);
            }
        }