Mongoose: Mongoose hangs indefinitely when disconnected

Created on 1 Oct 2016  路  9Comments  路  Source: Automattic/mongoose

I hava a koajs/mongoose REST service and when mongoDB goes down, all requests that hit my REST service hang indefinitely. I'm trying to configure mongoose in a way that it would fail any command when mongoose is not connected to mongo. Is this possible?
I have tried using bufferCommands: false on my Schemas but it doesn't seem to do anything.

Most helpful comment

Mongoose and the mongodb driver both have their own buffering layers (something we're hoping to remove in a subsequent release) so in order to have operations fail fast but the driver continues to reconnect in the background you need to:

1) Upgrade to 4.6.5 once it's released (should be today)
2) Disable mongoose buffering with bufferCommands: false in the schema
3) Set the driver's bufferMaxEntries to 0 like mongoose.connect(uri, { db: { bufferMaxEntries: 0 } })

All 9 comments

Can you show me how you're turning bufferCommands off? That should be sufficient...

Yes sir. Like this:

var schema = new Schema({..}, { bufferCommands: false });

My goal is that any subsequent request to mongo going down will fail immediately

Also have same issue.
After Mongo drops any other request like findOne will just hangs down infinite.

+1 we are seeing the same issue

Below script works fine for me:

'use strict';

Error.stackTraceLimit = Infinity;

var assert = require('assert');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/gh4581');
mongoose.set('debug', true);

var schema = new Schema({ name: String }, { bufferCommands: false });

var M = mongoose.model('Test', schema);

console.log('Waiting');
setTimeout(function() {
  console.log('Querying');
  M.findOne({}, function(error, res) {
    assert.ok(error);
    console.log('done');
    process.exit(0);
  });
}, 6000);

When I kill mongodb while the setTimeout is waiting, the connection emits a DisconnectedError after 30 seconds as expected:

$ node gh-4581.js 
Waiting
Mongoose: tests.findOne({}, { fields: undefined })

events.js:160
      throw er; // Unhandled 'error' event
      ^
DisconnectedError: Ran out of retries trying to reconnect to "localhost:27017". Try setting `server.reconnectTries` and `server.reconnectInterval` to something higher.
    at MongooseError.DisconnectedError (/home/val/Workspace/10gen/troubleshoot-mongoose/node_modules/mongoose/lib/error/disconnected.js:21:11)
    at .<anonymous> (/home/val/Workspace/10gen/troubleshoot-mongoose/node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js:64:31)
    at emitTwo (events.js:111:20)
    at emit (events.js:191:7)
    at .<anonymous> (/home/val/Workspace/10gen/troubleshoot-mongoose/node_modules/mongoose/node_modules/mongodb-core/lib/topologies/server.js:231:16)
    at g (events.js:286:16)
    at emitTwo (events.js:106:13)
    at emit (events.js:191:7)
    at .<anonymous> (/home/val/Workspace/10gen/troubleshoot-mongoose/node_modules/mongoose/node_modules/mongodb-core/lib/connection/pool.js:119:12)
    at g (events.js:286:16)
    at emitTwo (events.js:106:13)
    at emit (events.js:191:7)
    at Socket.<anonymous> (/home/val/Workspace/10gen/troubleshoot-mongoose/node_modules/mongoose/node_modules/mongodb-core/lib/connection/connection.js:151:49)
    at Socket.g (events.js:286:16)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at emitErrorNT (net.js:1272:8)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)

You should be able to turn server.autoReconnect off to get the behavior you want (fail immediately if server is disconnected) but unfortunately there's an issue in the underlying mongodb driver that prevents this (see https://github.com/christkv/mongodb-core/pull/147).

I'm seeing a similar issue but I am confused about the response from @vkarpov15 around the need to set autoReconnect off to get the desired behavior (if everthing was working). I assumed bufferCommands setting is independent of the autoReconnect setting? What I would hope for is a fast fail if bufferCommands: false (when connection is lost), BUT I still want autoReconnect to continue attempting to re-establish connection. I just don't want commands buffered in the interim. Currently, I have bufferCommands: false in my schema options but it appears to be effectively ignored. Query(find()) callbacks are never called during disconnect and then are executed upon reconnect event.
mongoose v4.6.3

I see the exact same behavior and I'd expect the same, mongoose to continue to attempt reconnection while dropping any commands that are executed while connection is down. Is this possible @vkarpov15 ?

Mongoose and the mongodb driver both have their own buffering layers (something we're hoping to remove in a subsequent release) so in order to have operations fail fast but the driver continues to reconnect in the background you need to:

1) Upgrade to 4.6.5 once it's released (should be today)
2) Disable mongoose buffering with bufferCommands: false in the schema
3) Set the driver's bufferMaxEntries to 0 like mongoose.connect(uri, { db: { bufferMaxEntries: 0 } })

@vkarpov15 Thanks. The described configuration steps worked.

Was this page helpful?
0 / 5 - 0 ratings