private void AckLater(MessageDispatch dispatch, AckType type)
{
// Don't acknowledge now, but we may need to let the broker know the
// consumer got the message to expand the pre-fetch window
if(this.session.IsTransacted)
{
this.session.DoStartTransaction();
if(!synchronizationRegistered)
{
Tracer.DebugFormat("Consumer {0} Registering new MessageConsumerSynchronization",
this.info.ConsumerId);
this.synchronizationRegistered = true;
this.session.TransactionContext.AddSynchronization(new MessageConsumerSynchronization(this));
}
}
this.deliveredCounter++;
MessageAck oldPendingAck = pendingAck;
pendingAck = new MessageAck();
pendingAck.AckType = (byte) type;
pendingAck.ConsumerId = this.info.ConsumerId;
pendingAck.Destination = dispatch.Destination;
pendingAck.LastMessageId = dispatch.Message.MessageId;
pendingAck.MessageCount = deliveredCounter;
if(this.session.IsTransacted && this.session.TransactionContext.InTransaction)
{
pendingAck.TransactionId = this.session.TransactionContext.TransactionId;
}
if(oldPendingAck == null)
{
pendingAck.FirstMessageId = pendingAck.LastMessageId;
}
else if(oldPendingAck.AckType == pendingAck.AckType)
{
pendingAck.FirstMessageId = oldPendingAck.FirstMessageId;
}
else
{
// old pending ack being superseded by ack of another type, if is is not a delivered
// ack and hence important, send it now so it is not lost.
if(oldPendingAck.AckType != (byte) AckType.DeliveredAck)
{
if(Tracer.IsDebugEnabled)
{
Tracer.Debug("Sending old pending ack " + oldPendingAck + ", new pending: " + pendingAck);
}
this.session.Connection.Oneway(oldPendingAck);
}
else
{
if(Tracer.IsDebugEnabled)
{
Tracer.Debug("dropping old pending ack " + oldPendingAck + ", new pending: " + pendingAck);
}
}
}
if((0.5 * this.info.PrefetchSize) <= (this.deliveredCounter - this.additionalWindowSize))
{
this.session.Connection.Oneway(pendingAck);
this.pendingAck = null;
this.deliveredCounter = 0;
this.additionalWindowSize = 0;
}
}