Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to notify a child process on SIGINT? #161

Closed
bennycode opened this issue May 10, 2018 · 1 comment
Closed

How to notify a child process on SIGINT? #161

bennycode opened this issue May 10, 2018 · 1 comment

Comments

@bennycode
Copy link
Contributor

I am using "forever-monitor" on Windows where child processes are detached by default.

In my application I have a monitor.js file which monitors a server.js file and I want to be able to notify server.js when I close my application by exiting monitor.js (hitting Ctrl + C in the terminal).

Here is my demo code:

monitor.js

const path = require('path');
const forever = require('forever-monitor');

let child;

function exit() {
  console.error('Received exit signal on main process.');
  if (child) {
    // TODO: Here I want to notify the "child", so that it can gracefully shutdown my server
    child.stop();
  }
  process.exit(0);
}

['SIGINT', 'SIGKILL', 'SIGTERM'].forEach(signal => process.on(signal, exit));

child = new forever.Monitor(path.join(__dirname, 'server.js'));
child.start();

server.js

const express = require('express');

const app = express();
const port = process.env.PORT || 8080;

let server;

function stopServer() {
  if (server) {
    console.log('Shutting down server...');
    server.close();
  }
}

app.get('/', (request, response) => response.send('Hello'));
server = app.listen(port, () => console.log(`Server is running on port "${port}".`));

How can I call stopServer in server.js when monitor.js receives a SIGINT?

@bennycode
Copy link
Contributor Author

bennycode commented May 10, 2018

I got it working! The secret sauce was to start the child process with option "fork". This made it possible to send messages to it using child.send. I now listen in the child process on a custom close message from the main process, so that I can stop my server and exit the child process with custom exit code 1337.

When the main process realizes that the child process has been closed with code 1337 (child.on('exit:code')), then the main process also shuts down.

Here is my solution:

monitor.js

const path = require('path');
const forever = require('forever-monitor');

let child;

function exit(signal) {
  console.error(`Received "${signal}" signal on main process.`);
  if (child) {
    child.send({action: 'close'});
  }
}

['SIGINT', 'SIGKILL', 'SIGTERM'].forEach(signal => process.on(signal, () => exit(signal)));

process.on('exit', (code) => console.log(`Stopped main process with code "${code}".`));

const options = {fork: true};

child = new forever.Monitor(path.join(__dirname, 'server.js'), options);

child.on('exit:code', (code) => {
  if (code === 1337) {
    if (child) {
      child.stop();
      console.log('Successfully stopped child process.');
    }
    console.log('Stopping main process ...');
    process.exit(0);
  }
});

child.start();

server.js

const express = require('express');

const app = express();
const port = process.env.PORT || 8080;

let server;

if (process.send) {
  process.on('message', function (message) {
    console.log(`Received "${message.action}" message from main process.`);
    if (message.action === 'close') {
      stopServer();
    }
  });
}

function stopServer() {
  if (server) {
    console.log('Stopping server in child process ...');
    server.close(() => {
      console.log('Stopped server in child process.');
      process.exit(1337);
    });
  }
}

app.get('/', (request, response) => response.send('Hello'));
server = app.listen(port, () => console.log(`Server is running on port "${port}".`));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant