如何使用Express.js正确处理SIGINT?

时间:2013-01-17 04:39:07

标签: node.js express sigint

SIGINT我的Express.js服务被var express = require('express'); var app = express(); var server = app.listen(3000); process.on('SIGINT', function() { console.log('Do something useful here.'); server.close(); }); 停止时,我需要做一些有用的事情。使用Express.js版本3.0.6,我知道这应该工作:

SIGINT

但是除非我两次发出$ node problem.js ^CDo something useful here. ^CDo something useful here. net.js:1046 throw new Error('Not running'); ^ Error: Not running at Server.close (net.js:1046:11) at process.<anonymous> (/path/to/problem.js:8:10) at process.EventEmitter.emit (events.js:93:17) at SignalWatcher.startup.processSignalHandlers.process.on.process.addListener.w.callback (node.js:486:45) $ Control - C ),否则该过程不会回复Bash提示符:

SIGINT

还有一点需要注意。如果我启动此Express.js服务并且不发送任何请求,那么{{1}}将正确终止。

显然,我在这里缺少一些基本的东西?

3 个答案:

答案 0 :(得分:26)

通过捕获SIGINT处理程序,您将阻止默认行为,即退出该进程。第二次使用Ctrl+C时,进程会因为server.close抛出未捕获的异常而死亡。

只需在process.exit()处理程序的末尾添加SIGINT即可正常退出该进程。

答案 1 :(得分:9)

我正在使用此代码:

server.close(() => {
  process.exit(0)
})

答案 2 :(得分:7)

由于问题没有完全(或正确)回答,人们可能仍会找到这个答案,因此复活了一个老人。

您问题的重要部分是:

还有一点需要注意。如果我启动此Express.js服务并且不发送任何请求,则SIGINT将正确终止。 显然,我在这里缺少一些基本的东西?

您缺少的是默认情况下,express保持连接打开(HTTP keep-alive)以便重复使用。因此,当有(最近的)请求时,事件循环中仍有某些内容,这就是您的应用未关闭的原因。

使用process.exit()会起作用,但就像发送另一个^ C一样,并且可能会隐藏仍有其他东西打开的事实(例如数据库连接)。当事件循环中没有任何内容时,您的应用应该关闭。

所以,我修改了你的例子,在连接上设置了5秒保持活动状态,以便在合理的时间内正常关闭。

&#13;
&#13;
var express = require('express');

var serverPort = 3000;
var app = express();
var server = app.listen(serverPort);


// HTTP Keep-Alive to a short time to allow graceful shutdown
server.on('connection', function (socket) {
  socket.setTimeout(5 * 1000);
});

// Handle ^C
process.on('SIGINT', shutdown);

// Do graceful shutdown
function shutdown() {
  console.log('graceful shutdown express');
  server.close(function () {
    console.log('closed express');
  });
}

console.log('running server: http://localhost:' + serverPort);
&#13;
&#13;
&#13;