_unacknowledgedMessageMap.visit(new UnacknowledgedMessageMap.Visitor()
{
public boolean callback(UnacknowledgedMessage message) throws AMQException
{
AMQShortString consumerTag = message.consumerTag;
AMQMessage msg = message.message;
msg.setRedelivered(true);
if (consumerTag != null)
{
// Consumer exists
if (_consumerTag2QueueMap.containsKey(consumerTag))
{
msgToResend.add(message);
}
else // consumer has gone
{
msgToRequeue.add(message);
}
}
else
{
// Message has no consumer tag, so was "delivered" to a GET
// or consumer no longer registered
// cannot resend, so re-queue.
if (message.queue != null)
{
if (requeue)
{
msgToRequeue.add(message);
}
else
{
_log.info("No DeadLetter Queue and requeue not requested so dropping message:" + message);
}
}
else
{
_log.info("Message.queue is null and no DeadLetter Queue so dropping message:" + message);
}
}
// false means continue processing
return false;
}
public void visitComplete()
{ }
});
// Process Messages to Resend
if (_log.isDebugEnabled())
{
if (!msgToResend.isEmpty())
{
_log.debug("Preparing (" + msgToResend.size() + ") message to resend.");
}
else
{
_log.debug("No message to resend.");
}
}
for (UnacknowledgedMessage message : msgToResend)
{
AMQMessage msg = message.message;
// Our Java Client will always suspend the channel when resending!
// If the client has requested the messages be resent then it is
// their responsibility to ensure that thay are capable of receiving them
// i.e. The channel hasn't been server side suspended.
// if (isSuspended())
// {
// _log.info("Channel is suspended so requeuing");
// //move this message to requeue
// msgToRequeue.add(message);
// }
// else
// {
// release to allow it to be delivered
msg.release(message.queue);
// Without any details from the client about what has been processed we have to mark
// all messages in the unacked map as redelivered.
msg.setRedelivered(true);
Subscription sub = msg.getDeliveredSubscription(message.queue);
if (sub != null)
{
// Get the lock so we can tell if the sub scription has closed.
// will stop delivery to this subscription until the lock is released.
// note: this approach would allow the use of a single queue if the
// PreDeliveryQueue would allow head additions.
// In the Java Qpid client we are suspended whilst doing this so it is all rather Mute..
// needs guidance from AMQP WG Model SIG
synchronized (sub.getSendLock())
{
if (sub.isClosed())
{
if (_log.isDebugEnabled())
{
_log.debug("Subscription(" + System.identityHashCode(sub)
+ ") closed during resend so requeuing message");
}
// move this message to requeue
msgToRequeue.add(message);
}
else
{
if (_log.isDebugEnabled())
{
_log.debug("Requeuing " + msg.debugIdentity() + " for resend via sub:"
+ System.identityHashCode(sub));
}
sub.addToResendQueue(msg);
_unacknowledgedMessageMap.remove(message.deliveryTag);