【问题标题】:How to notify a child process from forever monitor on SIGINT in parent process?如何在父进程的 SIGINT 上永久监控子进程?
【发布时间】:2018-10-20 17:23:13
【问题描述】:

我在 Windows 上使用forever-monitor,默认情况下child processes are detached

在我的应用程序中,我有一个 monitor.js 文件,它监视一个 server.js 文件,我希望能够在我通过退出 monitor.js 关闭我的应用程序时通知 server.js(在命令上点击 Ctrl + C -行)。

这是我的演示代码:

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}".`));

monitor.js 收到SIGINT 时,我如何在server.js 中调用stopServer

【问题讨论】:

    标签: node.js process forever sigint forever-monitor


    【解决方案1】:

    秘诀是使用“fork”选项启动子进程。

    使用“fork”选项可以通过调用child.send 将消息从父进程发送到子进程。这提供了在子进程中侦听来自父进程的自定义close 消息的能力,以便子进程可以停止服务器并使用自定义退出代码1337 退出。

    当父/主进程意识到子进程已用代码1337 关闭时,主进程也会关闭。

    这是我的解决方案:

    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}".`));
    

    【讨论】:

      最近更新 更多