I'm trying to properly close a MongoDB connection when the app is shut down. Here is the code:
我正在尝试在关闭应用程序时正确关闭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);
All is well and works when the app starts for the first time. When I hit Ctrl-c
right after it has started, it cleanly shuts down with the Closed out remaining connections.
message. However, as soon as the app interacts with the database or even serves a static page, and I try to shut it down after that, it exits with the following error:
当应用程序第一次启动时,一切都很顺利。当我在启动后立即按下Ctrl-c时,它会在关闭的剩余连接中干净地关闭。信息。但是,只要应用程序与数据库交互或甚至提供静态页面,我尝试在此之后将其关闭,它将退出并显示以下错误:
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
Any ideas what is causing this error and how I could fix it?
是什么原因造成了这个错误以及我如何解决它?
3 个解决方案
#1
4
When server.close is called, there are two properties that are checked.
调用server.close时,会检查两个属性。
handle<tcp handle>
connections
Responsible code fragment of server.close responsible for this error;
server.close的负责代码片段负责此错误;
if (!this._handle) {
// Throw error. Follows net_legacy behaviour.
throw new Error('Not running');
}
Only if handle===null and connections ===0 that the callback passed to close is called.
只有当handle === null和connections === 0时,才会调用传递给close的回调。
Case : Server is started and sent the signal with no serving.
案例:服务器启动并发送信号,没有服务。
Before close is called;
在关闭前调用;
handle === TCP handle.
connection===0;
After close handle===null; connection===0;
关闭句柄后=== null;连接=== 0;
The callback gets called.
调用回调。
Case : Server is started and sent the signal after a request server.
案例:服务器启动并在请求服务器之后发送信号。
Before close is called;
在关闭前调用;
handle === TCP.handle;
connection===1;
After close handle === null; connection===1;
关闭句柄后=== null;连接=== 1;
No callback is fired.
没有回调。
Second time when you press ctrl-c
第二次按ctrl-c
Before close is called;
在关闭前调用;
handle === null;
connection===1;
since handle===null , the check throws the error you are seeing.
因为句柄=== null,检查会抛出你看到的错误。
#2
2
The reason your server has open connections is because you are sending Connection: keep-alive
header.
您的服务器打开连接的原因是您发送Connection:keep-alive标头。
Morgan's answer closes all the connections on the server cleanly, disconnecting all of the clients.
Morgan的回答干净地关闭了服务器上的所有连接,断开了所有客户端的连接。
If you are just testing your application and want to shut it down cleanly before/after tests I recommend sending Connection: close
header and server.close()
will work as expected.
如果您只是测试您的应用程序并希望在测试之前/之后干净地关闭它,我建议发送Connection:close header和server.close()将按预期工作。
#3
1
I don't think setting server._connections = 0 actually closes the connection. It just satisfies the conditions to get your callback executed.
我不认为设置server._connections = 0实际上会关闭连接。它只是满足了执行回调的条件。
You might want to try something like this:
您可能想尝试这样的事情:
// 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() ...
}
#1
4
When server.close is called, there are two properties that are checked.
调用server.close时,会检查两个属性。
handle<tcp handle>
connections
Responsible code fragment of server.close responsible for this error;
server.close的负责代码片段负责此错误;
if (!this._handle) {
// Throw error. Follows net_legacy behaviour.
throw new Error('Not running');
}
Only if handle===null and connections ===0 that the callback passed to close is called.
只有当handle === null和connections === 0时,才会调用传递给close的回调。
Case : Server is started and sent the signal with no serving.
案例:服务器启动并发送信号,没有服务。
Before close is called;
在关闭前调用;
handle === TCP handle.
connection===0;
After close handle===null; connection===0;
关闭句柄后=== null;连接=== 0;
The callback gets called.
调用回调。
Case : Server is started and sent the signal after a request server.
案例:服务器启动并在请求服务器之后发送信号。
Before close is called;
在关闭前调用;
handle === TCP.handle;
connection===1;
After close handle === null; connection===1;
关闭句柄后=== null;连接=== 1;
No callback is fired.
没有回调。
Second time when you press ctrl-c
第二次按ctrl-c
Before close is called;
在关闭前调用;
handle === null;
connection===1;
since handle===null , the check throws the error you are seeing.
因为句柄=== null,检查会抛出你看到的错误。
#2
2
The reason your server has open connections is because you are sending Connection: keep-alive
header.
您的服务器打开连接的原因是您发送Connection:keep-alive标头。
Morgan's answer closes all the connections on the server cleanly, disconnecting all of the clients.
Morgan的回答干净地关闭了服务器上的所有连接,断开了所有客户端的连接。
If you are just testing your application and want to shut it down cleanly before/after tests I recommend sending Connection: close
header and server.close()
will work as expected.
如果您只是测试您的应用程序并希望在测试之前/之后干净地关闭它,我建议发送Connection:close header和server.close()将按预期工作。
#3
1
I don't think setting server._connections = 0 actually closes the connection. It just satisfies the conditions to get your callback executed.
我不认为设置server._connections = 0实际上会关闭连接。它只是满足了执行回调的条件。
You might want to try something like this:
您可能想尝试这样的事情:
// 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() ...
}