简体   繁体   中英

NodeJS + Mongoose timeout on connection

So I've read that mongoose driver for NodeJS caches queries until it connects to MongoDB (no timeouts). But when the db crashes it should be possible to send a message to the user. So let's look at this NodeJS code:

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

This may be hanging at 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)?

I handled this problem by adding one additional step in each router where I use DB.

It's a little bit messy but it works and 100% no leaks.

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.

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. This callback will be called with an Error object as argument if the connection cannot be opened. From mongoose' source (port and options are optional):

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

Alternatively, you can subscribe to the Connection's "error" event. 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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