rabbot icon indicating copy to clipboard operation
rabbot copied to clipboard

Shutdown stalls on queue topology error

Open MitMaro opened this issue 6 years ago • 1 comments

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

MitMaro avatar Mar 05 '18 17:03 MitMaro

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

antmarot avatar Dec 04 '18 13:12 antmarot