amqp / rhea

A reactive messaging library based on the AMQP protocol
Apache License 2.0
280 stars 79 forks source link

context.delivery.reject() not raising 'rejected' event #320

Closed marcelorubim closed 4 years ago

marcelorubim commented 4 years ago

Hello,

I'm running the script bellow againt a RabbitMQ (with AMPQ 1.0 plugin enabled).

Any reason why the message doesn't get rejected?

In fact, it raises the 'accepted' event. Even with the 'autoaccept' property setted to false in the receiver.

const container = require('rhea')

container.on('connection_open', function (context) {
    context.connection.open_receiver({
        source: {
            address: 'examples'
        },
        autoaccept: false
    });
    context.connection.open_sender('examples');
});
container.on('message', function (context) {
    console.log(context.message.body);
    context.delivery.reject();

});
container.once('sendable', function (context) {
    context.sender.send({body:'Hello World!'});
});
container.once('accepted', function (context) {
    console.log('accepted');
    context.connection.close();

});
container.once('rejected', function (context) {
    console.log('rejected');
    context.connection.close();

});
container.connect({'port':5672});
grs commented 4 years ago

In normal operation it is the receiver (not the sender) that rejects a message.

marcelorubim commented 4 years ago

Even if I attach the event to the consumer, I get the same outcome

container.on('connection_open', function (context) {
    console.log('connection_open')
    context.connection.open_receiver({
        source: {
            address: 'examples'
        },
        autoaccept: false
    }).on('message', function (context) {
        console.log(context.message.body);
        context.delivery.reject();

    });
    context.connection.open_sender('examples');
});
grs commented 4 years ago

Sorry, my previous response on re-reading was not very helpful.

The rejected event will be raised on the sender if the receiver rejects. However if you are sending through a broker, with a store-and-froward guarantee, then it is the broker that will see the reject not the original sender.

For the original sender to receive the reject you need to be connecting sender direct to receiver or using an intermediary that gives end to end guarantees such as Apache Qpid Dispatch Router. With that, running your first example, I see the rejected event being raised.

If you run that first example against a broker, the sent message may be accepted before the receiver has a chance to reject it, and the connection will be closed. If you comment out the connection close on accepted though, the broker does receive the reject. (The client won't get the event of course as it is not the sender of the message that is rejected).

marcelorubim commented 4 years ago

Now I get it! I'll only receive the reject, if the broker rejects it, not the consumer. Thanks!