0

So I started using RabbitMQ and doing the Tutorials on the Website https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html but i didnt 100% understand how can the aknowledge feature be set so that a Queue will delete the message immediately right after it sends the message, it doesnt matter wether the message will be consumed or not. I'm trying to make a Queue that will delete all the messages right after the sending happens

I tried the examples in the Tutorials for example the hello world example shows that the noAck property is set to true which means we are not acknowledging the messages so the Queue should actually delete those messages after they ve been sent but that's not the case because when i run send.js 3 times and then run receive.js then i ll receive 3 times hello world message which is not what i want

 // this is send.js
   var amqp = require('amqplib/callback_api');

  amqp.connect('amqp://localhost', function(error0, connection) {
  if (error0) {
    throw error0;
  }
 connection.createChannel(function(error1, channel) {
    if (error1) {
        throw error1;
    }

    var queue = 'hello';
    var msg = 'Hello World!';

    channel.assertQueue(queue, {
        durable: false
    });
    channel.sendToQueue(queue, Buffer.from(msg));

    console.log(" [x] Sent %s", msg);
});
setTimeout(function() {
    connection.close();
    process.exit(0);
}, 500);
  });

   // this is receive .js
     var amqp = require('amqplib/callback_api');

 amqp.connect('amqp://localhost', function(error0, connection) {
if (error0) {
    throw error0;
}
connection.createChannel(function(error1, channel) {
    if (error1) {
        throw error1;
    }

    var queue = 'hello';

    channel.assertQueue(queue, {
        durable: false
    });

    console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", 
   queue);

    channel.consume(queue, function(msg) {
        console.log(" [x] Received %s", msg.content.toString());
    }, {
        noAck: true
    });
});
});

for example if i run 3 times send.js there is 2 cases that can happen. case 1 is that the message will be consumed from the receiver and done. case2 is that it ll be not consumed from the receiver and in this case i want it to be deleted i dont want the message to be consumed if i run receive.js after a month from send.js, but i want also my Queue to be durable and not exclusive. it ll be also a Problem when i keep calling send.js and messages will be pushed all the time in that Queue and then if i run receive.js i ll receive a 1000 message at the same time so my goal is to avoid that. I appreciate any help

  • What you described is the principle of message queues -- producers create messages that are then all consumed by consumers in order. You didn't provide any specific requirement except that you don't want the message to stay in queue forever. For that, you can set [TTL](https://www.rabbitmq.com/ttl.html). – Tomáš Linhart Apr 23 '19 at 14:17
  • the noAck:true property will recognize the messages as consumed. it doesnt matter wether they are really consumed or not but what confuses me is what is the use of the noAck:True here ? it seems like it does nothing because if the messages are automaticlly acknowledge than the Queue must automatically delete them but it is not the case here with the amqplib in Node js – Nidhal Baccouri Apr 23 '19 at 16:25
  • IMHO `noAck` means no manual acknowledgement, so message gets automatically acknowledged once it's consumed no matter if it was processed or not. – Tomáš Linhart Apr 23 '19 at 16:50
  • ok but my goal is that it ll be deleted wether it was consumed or not. i dont want to run send.js 100 time and then when i run receive.js i ll receive 100 time the same message, how can i avoid that – Nidhal Baccouri Apr 23 '19 at 19:46
  • What's the point of sending the messages then if you don't want to consume them? What's your expected behavior after running `receive.js`? – Tomáš Linhart Apr 23 '19 at 19:51
  • let's say send.js will send a message but my service for consuming which is receive.js will crashed for some reason then it ll come back to work after some time, i dont want that when it come back to work again that it ll receive 100 message at the same time that'S why the goal is to delete the messages wether they ll be consumed or not. – Nidhal Baccouri Apr 23 '19 at 21:25

1 Answers1

0

What I think you want, after reading the comments and the question again, is that you want the message be either delivered to the consumer, or dropped if it can't be delivered at the moment it hits the queue. If this is the case, you can set the TTL to 0, either on the queue or on individual messages. From the relevant part of the documentation:

Setting the TTL to 0 causes messages to be expired upon reaching a queue unless they can be delivered to a consumer immediately.

To set the TTL of the queue, in your case of JavaScript client you need to modify the call to channel.assertQueue to include the arguments with x-message-ttl set to 0. Here's the example of the relevant part:

var queue = 'hello';
channel.assertQueue(queue, {
    durable: false,
    arguments: {
        "x-message-ttl": 0
    }
});

For more detailed information, consult the amqp.node documentation.

Tomáš Linhart
  • 9,832
  • 1
  • 27
  • 39