node-amqp-connection-manager icon indicating copy to clipboard operation
node-amqp-connection-manager copied to clipboard

exception handling into setup function - reconnection retry interval

Open ralcini opened this issue 9 years ago • 2 comments

Hi there,

in the following test case, an exception will be raised by the RabbitMq server due to the lack of authorization in assertExchange.

Disconnected. Error: Channel closed by server: 403 (ACCESS-REFUSED) with message "ACCESS_REFUSED - access to exchange 'assertFail' in vhost '/' refused for user 'test'"
    at ConfirmChannel.C.accept (/home/test/lib/node_modules/amqplib/lib/channel.js:403:24)
    at Connection.mainAccept [as accept] (/home/test/lib/node_modules/amqplib/lib/connection.js:62:33)
    at Socket.go (/home/test/availability-agent/lib/node_modules/amqplib/lib/connection.js:465:48)
    at Socket.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:427:10)
    at emitReadable (_stream_readable.js:423:5)
    at readableAddChunk (_stream_readable.js:166:9)
    at Socket.Readable.push (_stream_readable.js:128:10)
    at TCP.onread (net.js:529:21)

The final outcome is a tight recconection loop that will not respect the reconnectTimeInSeconds directive. I expeted to see retry attempts every reconnectTimeInSeconds

var amqp = require('amqp-connection-manager');

var connection = amqp.connect(['amqp://test:[email protected]:5672'], {reconnectTimeInSeconds: 5, json: true});
connection.on('connect', function() {
    console.log('Connected!');
});
connection.on('disconnect', function(params) {
    console.log('Disconnected.', params.err.stack);
});

// Set up a channel listening for messages in the queue.
var channelWrapper = connection.createChannel({
    setup: function(channel) {
        return  channel.assertExchange("assertFail");
    }
});

channelWrapper.waitForConnect().then(function() {
    console.log("Listening for messages");
});

channelWrapper.on('connect', function(){console.log("connect")})
channelWrapper.on('error', function(){console.log("error")})
channelWrapper.on('drop', function(){console.log("drop")})
channelWrapper.on('close', function(){console.log("close")})

ralcini avatar Sep 23 '15 19:09 ralcini

Don't know how I missed the notification for this, but sorry I didn't see this issue until now. :(

Hm... Interesting. I wouldn't have thought that failing to create a channel would take out the whole connection. But yes, we only wait for the retry timeout here, when connecting fails, and in your case we are connecting OK, but then the connection blows up on us immediately afterwards. The simplest fix that comes to mind it to record the last reconnect time, and then when we start a new connection attempt, always make sure we wait until we're at least reconnectTimeInSeconds from the last attempt.

I'd welcome a PR.

jwalton avatar Jan 25 '16 20:01 jwalton

Not sure if this was ever fixed but I'm having a similar issue when the exchange doesn't exist. In most cases I guess this is asserted before so may not have been caught.

adamlc avatar Jan 24 '18 11:01 adamlc