rabbot
rabbot copied to clipboard
Shutdown stalls on queue topology error
Description
When there is a precondition failure on a queue during configure
it is not possible to gracefully shutdown Rabbot.
Expected Behaviour
Calling rabbot.shutdown()
after a connection to the RabbitMQ server has been made, but on failed rabbot.configure(topology)
call should gracefully shutdown Rabbot allowing the Node process to exit.
Actual Behaviour
Calling rabbot.shutdown()
as described above never resolves and does not allow the node process to shutdown.
Reduced Test Case
Repository: https://github.com/MitMaro/rabbot-configure-error-shutdown-error
const rabbot = require('rabbot');
const wtf = require('wtfnode');
const connectionConfig = {
name: 'default',
host: 'localhost', // TODO Change
user: 'user', // TODO Change
pass: 'password', // TODO Change
};
const topology = {
connection: connectionConfig,
queues:[
{
name: 'acme.queue.system.1',
messageTtl: Number(process.argv[2]),
},
],
};
rabbot
.addConnection(connectionConfig)
.then(() => rabbot.configure(topology))
.then(() => {
console.log('Successfully configured Rabbot, shutting down')
rabbot.shutdown();
})
.catch((err) => {
console.log('Error caught')
console.log(err);
console.log()
setTimeout(() => {
wtf.dump();
}, 1000);
console.log('Shutting down')
return rabbot
.shutdown()
.then(() => {
// never gets here
console.log('Shutdown complete')
});
;
})
;
Instructions
See Detailed Instructions for more information.
-
npm install
- Update connection parameters
-
node index.js 100
-
node index.js 1000
Investigation
I couldn't determine why, but using wtfnode
I was able to get the list of open handlers that are keeping Node from shutting down.
[WTF Node?] open handles:
- File descriptors: (note: stdio always exists)
- fd 1 (tty) (stdio)
- fd 2 (tty) (stdio)
- Sockets:
- 169.254.254.254:55696 -> 169.254.254.254:5672
- Timers:
- (1 ~ 1 undefined) bound @ /Users/timoram/code/broken-project-test-cases/timers-after-failed-configuration/node_modules/rabbot/src/amqp/iomonad.js:283
- Intervals:
- (15000 ~ 15 s) bound @ /Users/timoram/code/broken-project-test-cases/timers-after-failed-configuration/node_modules/amqplib/lib/heartbeat.js:65
- (30000 ~ 30 s) bound @ /Users/timoram/code/broken-project-test-cases/timers-after-failed-configuration/node_modules/amqplib/lib/heartbeat.js:74
- (500 ~ 500 ms) (anonymous) @ /Users/timoram/code/broken-project-test-cases/timers-after-failed-configuration/node_modules/rabbot/src/index.js:500
I have the same issue, even if the configure call eventually succeeds (using retry strategy from https://github.com/arobson/rabbot/issues/108#issuecomment-442787962).
[WTF Node?] open handles:
- File descriptors: (note: stdio always exists)
- fd 1 (stdio)
- fd 2 (stdio)
- Sockets:
- 172.26.0.4:53354 -> 172.26.0.2:5672
- Intervals:
- (15000 ~ 15 s) bound @ /usr/src/app/node_modules/amqplib/lib/heartbeat.js:65
- (30000 ~ 30 s) bound @ /usr/src/app/node_modules/amqplib/lib/heartbeat.js:74
- (500 ~ 500 ms) (anonymous) @ /usr/src/app/node_modules/rabbot/src/index.js:500