9

アプリのシャットダウン時に MongoDB 接続を適切に閉じようとしています。コードは次のとおりです。

var express = require('express')
  , http = require('http')
  , mongoose = require('mongoose')
  , path = require('path');

var app = express();

app.set('port', process.env.PORT || 3000);

mongoose.connect('mongodb://localhost/test');

// some post and get handlers etc. (removed for shorter output)

var server = app.listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));
});

function cleanup () {
    server.close(function () {
        console.log("Closed out remaining connections.");
        mongoose.connection.close();
        process.exit();
    });

    setTimeout( function () {
        console.error("Could not close connections in time, forcing shut down");
        process.exit(1);
    }, 30*1000);
}

process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);

すべてが順調で、アプリを初めて起動したときに機能します。Ctrl-c開始直後にヒットすると、Closed out remaining connections.メッセージできれいにシャットダウンします。ただし、アプリがデータベースとやり取りしたり、静的ページを提供したりするとすぐに、その後シャットダウンしようとすると、次のエラーで終了します。

net.js:1225
    throw new Error('Not running');
          ^
Error: Not running
    at Server.close (net.js:1225:11)
    at process.cleanup (<...>/app.js:77:12)
    at process.EventEmitter.emit (events.js:92:17)
    at Signal.wrap.onsignal (node.js:756:46)
22 Aug 15:15:28 - [nodemon] exiting

このエラーの原因と修正方法はありますか?

4

3 に答える 3

4

server.close が呼び出されると、チェックされる 2 つのプロパティがあります。

   handle<tcp handle>
   connections

このエラーの原因となる server.close の責任あるコード フラグメント。

  if (!this._handle) {
    // Throw error. Follows net_legacy behaviour.
    throw new Error('Not running');
  }

コールバックが close に渡した handle===null および connections ===0 が呼び出された場合のみ。

ケース : サーバーが開始され、サービスなしでシグナルが送信されます。

close が呼び出される前。

  handle === TCP handle.
  connection===0;

ハンドルを閉じた後===null; 接続===0;

コールバックが呼び出されます。

ケース : サーバーが開始され、リクエスト サーバーの後にシグナルが送信されます。

close が呼び出される前。

  handle === TCP.handle;
  connection===1;

ハンドルを閉じた後 === null; 接続===1;

コールバックは発生しません。

ctrl-c を 2 回押したとき

close が呼び出される前。

  handle === null;
  connection===1;

handle===null であるため、チェックは表示されているエラーをスローします。

于 2013-08-22T15:03:18.703 に答える
2

サーバーが接続を開いている理由は、Connection: keep-aliveヘッダーを送信しているためです。

モーガンの答えは、サーバー上のすべての接続をきれいに閉じ、すべてのクライアントを切断します。

アプリケーションをテストしているだけで、テストの前後にきれいにシャットダウンしたい場合は、Connection: closeヘッダーを送信することをお勧めserver.close()します。期待どおりに動作します。

于 2015-09-08T18:14:48.900 に答える
1

server._connections = 0 を設定しても実際に接続が閉じられるとは思いません。コールバックを実行するための条件を満たしているだけです。

次のようなことを試してみてください。

// Everything else how you had it before ...

var sockets = [];

server.on('connection', function(socket) {
  sockets.push(socket);
});

function cleanup () {
  server.close(function () {
    console.log("Closed out remaining connections.");
     // mongoose.connection.close(); Might want to comment this out
    process.exit();
  });

  // Add this part to manually destroy all the connections.
  sockets.forEach(function(socket) {
    socket.destroy();
  });

  // setTimeout() ...
}
于 2014-02-13T03:43:47.343 に答える