简体   繁体   English

NodeJS +连接时的Mongoose超时

[英]NodeJS + Mongoose timeout on connection

So I've read that mongoose driver for NodeJS caches queries until it connects to MongoDB (no timeouts). 所以我已经读过NodeJS的mongoose驱动程序缓存查询,直到它连接到MongoDB(没有超时)。 But when the db crashes it should be possible to send a message to the user. 但是当db崩溃时,应该可以向用户发送消息。 So let's look at this NodeJS code: 那么让我们来看看这个NodeJS代码:

Users.find({}, function(err, result) {
  // Do something with result and send response to the user
});

This may be hanging at infintum. 这可能会挂在infintum上。 So one way to fix this problem is to do the following 因此,解决此问题的一种方法是执行以下操作

var timeout = setTimeout(function() {
  // whem we hit timeout, respond to the user with appropriate message
}, 10000);

Users.find({}, function(err, result) {
  clearTimeout(timeout);  // forget about error
  // Do something with result and send response to the user
});

And the question is: is this a good way? 问题是:这是一个好方法吗? What about memory leaks (hanging queries to MongoDB)? 那么内存泄漏(挂起对MongoDB的查询)?

I handled this problem by adding one additional step in each router where I use DB. 我通过在每个使用DB的路由器中添加一个额外步骤来处理此问题。

It's a little bit messy but it works and 100% no leaks. 它有点乱,但它有效,100%没有泄漏。

Something like this: 像这样的东西:

// file: 'routes/api/v0/users.js'
router
var User = require('../../../models/user').User,
    rest = require('../../../controllers/api/v0/rest')(User),
    checkDB = require('../../../middleware/checkDB');

module.exports = function (app) {
  app.get('/api/v0/users', checkDB, rest.get);
  app.get('/api/v0/users/:id', checkDB, rest.getById);
  app.post('/api/v0/users', checkDB, rest.post);
  app.delete('/api/v0/users', checkDB, rest.deleteById);
  app.put('/api/v0/users', checkDB, rest.putById);
};

// file: 'middleware/checkDB.js'
var HttpError = require('../error').HttpError,
    mongoose = require('../lib/mongoose');

// method which checks is DB ready for work or not
module.exports = function(req, res, next) {
  if (mongoose.connection.readyState !== 1) {
    return next(new HttpError(500, "DataBase disconnected"));
  }
  next();
};

PS If you know solution better, please let me know. PS如果你更了解解决方案,请告诉我。

I hope I'm understanding your question correctly, I think you're worried that, because mongoose takes an optimistic pattern and lets you take for granted that it will connect eventually, you're afraid you won't be able to gracefully handle the case when the connection fails. 我希望我能正确地理解你的问题,我觉得你很担心,因为猫鼬采取了乐观的模式并让你理所当然地认为它最终将会联系起来,你担心你将无法优雅地处理连接失败的情况。

The Connection.open() method accepts a callback as last argument. Connection.open()方法接受回调作为最后一个参数。 This callback will be called with an Error object as argument if the connection cannot be opened. 如果无法打开连接,则将使用Error对象作为参数调用此回调。 From mongoose' source (port and options are optional): 来自mongoose'源码(端口和选项是可选的):

Connection.prototype.open = function (host, database, port, options, callback)

Alternatively, you can subscribe to the Connection's "error" event. 或者,您可以订阅Connection的“错误”事件。 It also receives the error object as argument. 它还接收错误对象作为参数。 However, it is only emitted if all arguments (and state) are valid, while the callback gets called every time, even if, for example, something goes wrong before the actual connection attempt (such as the connection not being in a readyState), and even if the connection is successful (in which case the error argument is null). 但是,只有在所有参数(和状态)都有效的情况下才会发出它,而每次都会调用回调,即使例如在实际连接尝试之前出现问题(例如连接不在readyState中),即使连接成功(在这种情况下,error参数为null)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM