Reputation: 54782
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
on the command-line).
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
?
Upvotes: 2
Views: 790
Reputation: 54782
The secret sauce is to start the child process with option "fork".
Using the "fork" option makes it possible to send messages from the parent process to the child process by calling child.send
. This gives the ability to listen in the child process on a custom close
message from the parent process, so that the child can stop the server and exit with custom exit code 1337
.
When the parent/main process realizes that the child process has been closed with code 1337
, 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}".`));
Upvotes: 2