[rabbitmq-discuss] Redelivery of unacknowledged messages
Ben Hood
0x6e6562 at gmail.com
Tue Sep 30 01:59:33 BST 2008
Jonatan,
On Mon, Sep 29, 2008 at 10:34 PM, Jonatan Kallus <jonatan at heysan.com> wrote:
> I get the feeling that this should be a rather basic question, but I have
> searched the mailing list and the AMQP specification without finding
> answers.
I did answer this last week, but it was off list and I'm still waiting
for confirmation to turn it into a list topic.
> For how long does the server wait for acknowledgment from a subscriber (when
> acknowledgment is required)?
>
> When are unacknowledged messages redelivered?
After the channel in which the initial receive has been closed and a
new channel has been setup.
> In my set up, using the java api for a single consumer and the stomp gateway
> and a php stomp client for sending messages to the queue, messages do not
> seem to get redelivered until the consumer is restarted.
This example code may illustrate the mechanism:
package com.acme;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.GetResponse;
import com.rabbitmq.client.MessageProperties;
public class AckExample {
// Using JDK assertions: add -ea flag to the interpreter
public static void main(String[] args) throws Exception {
final Connection con = new
ConnectionFactory().newConnection("0.0.0.0", 5672);
Channel channel = con.createChannel();
String q = "foo" + System.currentTimeMillis();
byte[] msg = ("bar" + System.currentTimeMillis()).getBytes();
channel.queueDeclare(1, q);
// Send 1 message
channel.basicPublish(1, "", q, MessageProperties.BASIC, msg);
// Synchronous receive with acknowledgements turned on
GetResponse response1 = channel.basicGet(1, q, false);
assert null != response1.getBody();
assert false == response1.getEnvelope().isRedeliver();
// Deliberately forget to ack the message and nuke the channel
channel.close(200, "hasta la vista, baby");
// Start a new channel
channel = con.createChannel();
// Get the same message
GetResponse response2 = channel.basicGet(1, q, false);
assert null != response2.getBody();
assert true == response2.getEnvelope().isRedeliver();
channel.close(200, "hasta la vista, baby");
con.close();
assert response1.getEnvelope().getDeliveryTag() ==
response2.getEnvelope().getDeliveryTag();
}
}
This uses the fact that an un-acked message will get redelivered on a
different channel if the original get command set the to no-ack flag
to false and no ack was received on this channel. Crude, but it works.
HTH,
Ben
More information about the rabbitmq-discuss
mailing list