Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using useUnifiedTopology: true, mongoose connection status is not always updated #8692

Closed
moisesjbc opened this issue Mar 20, 2020 · 1 comment
Labels
help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary

Comments

@moisesjbc
Copy link

moisesjbc commented Mar 20, 2020

Do you want to request a feature or report a bug?

A bug

What is the current behavior?

When using useUnifiedTopology: true, mongoose connection status is not updated according to underlying Mongo instance disconnecting and reconnecting. Also "disconnected" and "reconnected" events are not always fired.

If the current behavior is a bug, please provide the steps to reproduce.

I have the following code:

var mongoose = require('mongoose');

setTimeout(() => {}, 10000);

mongoose.connection.once('open', function() {
    console.log('---> connected!');
});

mongoose.connection.on('disconnected', function() {
    console.log('---> disconnected!', mongoose.connection.readyState);
});

mongoose.connection.on('reconnected', function() {
    console.log('---> reconnected!', mongoose.connection.readyState);
});

mongoose.connect('mongodb://localhost:5555', {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
    useFindAndModify: false
});

And I use the following test script, which starts and stops Mongo regularly (mind the killall!)

#!/bin/bash

echo "starting mongo"; mongod --port 5555 > /dev/null 2>&1 &
sleep 3
echo "starting node"; node sample.js &
sleep 3

while :
do
    echo "stoping mongo"; killall mongod
    sleep 3
    echo "starting mongo"; mongod --port 5555 --dbpath data/db > /dev/null 2>&1 &
    sleep 3
done

The log is as follows:

starting mongo
starting node
---> connected!
stoping mongo
starting mongo
stoping mongo
---> disconnected! 0
starting mongo
stoping mongo
starting mongo
---> reconnected! 1
stoping mongo
starting mongo
stoping mongo

As you can see, state is not always updated. If I comment or remove useUnifiedTopology: true, the status is always updated, but I get the deprecation warning:

starting mongo
starting node
(node:26742) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
---> connected!
stoping mongo
---> disconnected! 0
starting mongo
---> reconnected! 1
stoping mongo
---> disconnected! 0
starting mongo
---> reconnected! 1
stoping mongo
---> disconnected! 0
starting mongo
---> reconnected! 1

What is the expected behavior?

I would expect the status to always update when using useUnifiedTopology: true.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

  • Node: v12.15.0
  • Mongoose: v5.9.5
  • MongoDB: v4.0.13
@vkarpov15 vkarpov15 modified the milestones: 5.9.6, 5.9.7 Mar 23, 2020
@vkarpov15 vkarpov15 modified the milestones: 5.9.7, 5.9.8 Mar 30, 2020
@vkarpov15
Copy link
Collaborator

I can confirm the readyState is updated, it just takes a little while based on the value of the serverSelectionTimeoutMS option. For example, consider the below script:

var mongoose = require('mongoose');

mongoose.connection.once('open', function() {
    console.log('---> connected!');
});

mongoose.connection.on('disconnected', function() {
    console.log(new Date(), '---> disconnected!', mongoose.connection.readyState);
});

mongoose.connection.on('reconnected', function() {
    console.log(new Date(), '---> reconnected!', mongoose.connection.readyState);
});

mongoose.connect('mongodb://localhost:27017', {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
    useFindAndModify: false,
    serverSelectionTimeoutMS: 5000
});

It can take up to 10 seconds for the 'connected' event to fire, because the MongoDB driver will try to send its internal heartbeat for serverSelectionTimeoutMS before declaring the heartbeat failed and letting Mongoose know to emit 'disconnected'.

$ node gh-8692.js 
---> connected!
2020-04-04T19:49:20.410Z '---> disconnected!' 0
2020-04-04T19:49:30.422Z '---> reconnected!' 1
^C

If you want faster feedback on disconnects, you should decrease serverSelectionTimeoutMS (how long before the MongoDB driver gives up on a given operation) and/or decrease heartbeatFrequencyMS (how often the MongoDB driver sends heartbeats). Just don't make heartbeatFrequencyMS too low or you'll DoS your own server.

mongoose.connect('mongodb://localhost:27017', {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex: true,
    useFindAndModify: false,
    serverSelectionTimeoutMS: 2000,
    heartbeatFrequencyMS: 2000
});

@vkarpov15 vkarpov15 added the help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary label Apr 4, 2020
@vkarpov15 vkarpov15 removed this from the 5.9.8 milestone Apr 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary
Projects
None yet
Development

No branches or pull requests

2 participants