node-death icon indicating copy to clipboard operation
node-death copied to clipboard

Node-Death SIGINT working fine on windows, but not gracefully shutting down services on Linux or MacOS platform

Open siddkar opened this issue 7 years ago • 5 comments

Hi Team,

Issue: I'm using node-death in my project. Node-Death is working fine when I'm running my application in Windows platform. On 'SIGINT' (ctrl+c) its gracefully shutting down the open connections made in my application. But when I issue 'SIGINT' signal from either MacOS or Linux platforms it, immediately shuts down the application without graceful shutdown of open connections. I have also used 'process.stdin.resume()' to prevent immediate shutdown, but still doesn't work.

Please find below my code:

import ON_DEATH from 'death';
import mongoose from './db.config';
import redisClient from './redis.config';
import { logger } from './pino.config';

const logError = (from, code, error) => {
    logger.error({ from, code, error });
};

const logInfo = connectionName => (logger.info({ message: `Connection with ${connectionName} shutdown gracefully!!!` }));

const shutdownRedis = () => redisClient.quit();

const shutdownMongoose = () => mongoose.connection.close(false);

// Begin reading from stdin so the process does not exit.
process.stdin.resume();

const onDeathCallback = async () => {
    try {
        await shutdownRedis();
        logInfo('Redis');
        await shutdownMongoose();
        logInfo('Mongo');
    } catch (err) {
        logError('death.config.onDeathCallback', 'ERR_GRACEFUL_CONN_SHUTDOWN', err);
    }
};

ON_DEATH(onDeathCallback);

Expected Output: Connection with Redis shutdown gracefully!!! Connection with Mongo shutdown gracefully!!!

Actual Output: No output as it doesn't execute the callback

Please kindly let me know if I'm doing anything wrong with the configurations. Looking forward to your help/reply on the above issue.

Thanks & Regards, Siddharth

siddkar avatar Aug 18 '18 07:08 siddkar

Deleted my prior comment because it was it had bad inferences and I've gotten to the bottom of my own situation through some experimentation. And what I thought might be related to this issue is not.

In my previous comment I suggested this might have something to do with process exit events in node only being able to do synchronous work. This is true for the process exit event, but because death replaces the default handlers for SIGINT and SIGTERM the process exit event isn't firing, so you can do async work, and node will wait for for things to complete...

So @siddkar I have no idea why you are not seeing things. I'd maybe isolate your experiment and reduce the variables to see what's going on?

@jprichardson I'm still interested if you still use this library, and what your thoughts are regarding using this for uncaught exceptions, and whether or not async work should be attempted after an uncaught exception.

From what I've read... it sounds like async should not be attempted during an uncaught exception? I'm mostly curious as to what a good practice is around node and shut downs...

rickbergfalk avatar Sep 14 '18 23:09 rickbergfalk

Also @siddkar for what it is worth, when I tried an experiment with death using process.stdin.resume();, I was not able to exit node with ctrl+c at all. Death would fire but because stdin was reading input node wouldn't close the process.

rickbergfalk avatar Sep 14 '18 23:09 rickbergfalk

Any update on this? I'm having the same issue here.

victorperin avatar Nov 14 '18 11:11 victorperin

Maybe problem is in async/wait? I suspect that you must perform exit actions without microtasks

ukrbublik avatar Sep 26 '19 14:09 ukrbublik

Try this:

const onDeathCallback = () => {
    try {
        shutdownRedis();
        logInfo('Redis');
        shutdownMongoose();
        logInfo('Mongo');
    } catch (err) {
        logError('death.config.onDeathCallback', 'ERR_GRACEFUL_CONN_SHUTDOWN', err);
    }
};

ukrbublik avatar Sep 26 '19 14:09 ukrbublik