Apache.NMS.ActiveMQ.MessageConsumer.Rollback C# (CSharp) Method

Rollback() private method

private Rollback ( ) : void
return void
        private void Rollback()
        {
            lock(this.unconsumedMessages.SyncRoot)
            {
                lock(this.dispatchedMessages)
                {
                    if(this.dispatchedMessages.Count == 0)
                    {
                        Tracer.DebugFormat("Consumer {0} Rolled Back, no dispatched Messages",
                                           this.info.ConsumerId);
                        return;
                    }

                    // Only increase the redelivery delay after the first redelivery..
                    MessageDispatch lastMd = this.dispatchedMessages.First.Value;
                    int currentRedeliveryCount = lastMd.Message.RedeliveryCounter;

                    redeliveryDelay = this.redeliveryPolicy.RedeliveryDelay(currentRedeliveryCount);

                    MessageId firstMsgId = this.dispatchedMessages.Last.Value.Message.MessageId;

                    foreach(MessageDispatch dispatch in this.dispatchedMessages)
                    {
                        // Allow the message to update its internal to reflect a Rollback.
                        dispatch.Message.OnMessageRollback();
                    }

                    if(this.redeliveryPolicy.MaximumRedeliveries >= 0 &&
                       lastMd.Message.RedeliveryCounter > this.redeliveryPolicy.MaximumRedeliveries)
                    {
                        // We need to NACK the messages so that they get sent to the DLQ.
                        MessageAck ack = new MessageAck();

                        ack.AckType = (byte) AckType.PoisonAck;
                        ack.ConsumerId = this.info.ConsumerId;
                        ack.Destination = lastMd.Destination;
                        ack.LastMessageId = lastMd.Message.MessageId;
                        ack.MessageCount = this.dispatchedMessages.Count;
                        ack.FirstMessageId = firstMsgId;

                        this.session.SendAck(ack);

                        // Adjust the window size.
                        additionalWindowSize = Math.Max(0, this.additionalWindowSize - this.dispatchedMessages.Count);

                        this.redeliveryDelay = 0;
                    }
                    else
                    {
                        // We only send a RedeliveryAck after the first redelivery
                        if(currentRedeliveryCount > 0)
                        {
                            MessageAck ack = new MessageAck();

                            ack.AckType = (byte) AckType.RedeliveredAck;
                            ack.ConsumerId = this.info.ConsumerId;
                            ack.Destination = lastMd.Destination;
                            ack.LastMessageId = lastMd.Message.MessageId;
                            ack.MessageCount = this.dispatchedMessages.Count;
                            ack.FirstMessageId = firstMsgId;

                            this.session.SendAck(ack);
                        }

                        // stop the delivery of messages.
                        this.unconsumedMessages.Stop();

                        if(Tracer.IsDebugEnabled)
                        {
                            Tracer.DebugFormat("Consumer {0} Rolled Back, Re-enque {1} messages",
                                               this.info.ConsumerId, this.dispatchedMessages.Count);
                        }

                        foreach(MessageDispatch dispatch in this.dispatchedMessages)
                        {
                            this.unconsumedMessages.EnqueueFirst(dispatch);
                        }

                        if(redeliveryDelay > 0 && !this.unconsumedMessages.Closed)
                        {
                            DateTime deadline = DateTime.Now.AddMilliseconds(redeliveryDelay);
                            ThreadPool.QueueUserWorkItem(this.RollbackHelper, deadline);
                        }
                        else
                        {
                            Start();
                        }
                    }

                    this.deliveredCounter -= this.dispatchedMessages.Count;
                    this.dispatchedMessages.Clear();
                }
            }

            // Only redispatch if there's an async listener otherwise a synchronous
            // consumer will pull them from the local queue.
            if(this.listener != null)
            {
                this.session.Redispatch(this.unconsumedMessages);
            }
        }