Express.js サービスがSIGINT
によって停止されたときに、いくつかの便利なことを行う必要があります。 Express.jsバージョン3.0.6を使用して、これが機能することを理解しています。
var express = require('express');
var app = express();
var server = app.listen(3000);
process.on('SIGINT', function() {
console.log('Do something useful here.');
server.close();
});
しかし、SIGINT
(を発行しない限り、プロセスはBashプロンプトを返しません。Control-C)2回:
$ 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)
$
もう1つの注意点。このExpress.jsサービスを開始し、リクエストを送信しない場合、SIGINT
は正しく終了します。
明らかに、私がここで見逃している基本的な何かがありますか?
SIGINT
ハンドラーをキャッチすることで、プロセスを終了するデフォルトの動作を防ぐことができます。 2回目に_Ctrl+C
_を使用すると、_server.close
_がキャッチされない例外をスローするため、プロセスが終了します。
SIGINT
ハンドラーの最後にprocess.exit()
を追加するだけで、プロセスを正常に終了できます。
質問が完全に(または正しく)答えられておらず、人々がまだこの答えを見つける可能性があるため、オールディーズを復活させる。
あなたの質問の重要な部分は次のとおりです。
もう1つの注意点。このExpress.jsサービスを開始し、リクエストを送信しない場合、SIGINTは正しく終了します。明らかに、ここで欠落している基本的なものがありますか? `
不足しているのは、デフォルトでExpressが再利用のために接続を開いたままにする(HTTPキープアライブ)ことです。したがって、(最近の)リクエストがあった場合でも、イベントループに何かがあり、それがアプリが閉じない理由です。
process.exit()
を使用することは機能しますが、別の^ Cを送信するようなものであり、他に何かが開いているという事実(データベース接続など)を隠す可能性があります。イベントループに何も残っていない場合は、アプリを閉じる必要があります。
そこで、例を変更して、接続に5秒のキープアライブを設定し、妥当な時間内に正常にシャットダウンするようにしました。
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);
私はこのコードを使用しています:
server.close(() => {
process.exit(0)
})