0

I am trying to implement a common module for MongoDB connection using mongoose. and want to use the connection in other application for database operation. but facing issue when trying to use common database module. operation is halted / hanging after creating db connection. here is my codebase.

When I am using module specific dababase connection, then it is working fine, but when I am using common database connection it is hanging

Common DB Module

'use strict'

const mongoose    = require('mongoose');
const DBOptions   = require('./DBOption');
require("dotenv").config();
mongoose.Promise = global.Promise;
let isConnected;

const connectToDatabase = (MONGODB_URL) => {

  if (isConnected) {
    console.log('using existing database connection');
    return Promise.resolve();
  }

  console.log('using new database connection');
  console.log('DBOptions >> '+JSON.stringify(DBOptions));
  
  return mongoose.connect(MONGODB_URL, DBOptions)
        .then(db => { 
          console.log('db.connections[0].readyState >> '+db.connections[0].readyState);
          isConnected = db.connections[0].readyState;
        });
};
 
module.exports = connectToDatabase;

API Controller

const dbConnection      = require('../DB/connection') // Internal Class
const DBConnection      = require('as-common-util').connectToDatabase; // Common Class

/**
 * 
 */
app.get('/usr/alluser', async (req, res) => {
  try {
    //await dbConnection(process.env.MONGODB_URL) // This is working
    await DBConnection(process.env.MONGODB_URL) // Code is hanging for this
    let allUsers = await UserService.getAllUser()
    console.log("All Users >> " + allUsers)
    if (allUsers) {
      return res.status(200).send(
        new APIResponse({
          success: true,
          obj: allUsers
        })
      )
    }
  } catch (error) {
    console.log(error)
  }
})

It is hanging at following position

using new database connection
DBOptions >>   
{"useNewUrlParser":true,"useUnifiedTopology":true,"useCreateIndex":true,"useFindAndModify":false,"autoIndex":false,"poolSize":10,"serverSelectionTimeoutMS":5000,"socketTimeoutMS":45000,"family":4}
db.connections[0].readyState >> 1

I am confused why same code is not working for common module.

ajoy sinha
  • 1,156
  • 4
  • 14
  • 30

1 Answers1

1

This kind of pattern is not how Mongoose is meant to be used. Under the hood, Mongoose passes the underlying connection to the models in your module without the user really knowing anything about what is going on. That's why you can do magic stuff like MyModel.find() without ever having to create a model object yourself, or pass a db connection object to it.

If your db connection is in another module though, Mongoose won't be able to make those connections between your models and the MongoDB client connection since the models are no longer being registered on the mongoose object that is actually connected, and as a result, any requests you make using your models will break, since they will always be trying to connect through the object in your module.

There are other reasons why this won't, and shouldn't, work though. You're not supposed to be able to split a client. Doing so would make it unclear where communication along a client is coming from, or going to. You could change your function to make it return an established client connection. But your Mongoose models still wouldn't work. You would just be left with raw mongodb. If you want to do that, you might as well just uninstall Mongoose and use the mongodb library. Ultimately, you don't really gain anything from initializing the connection in a shared module. Initializing a connection is just a couple lines of code.

I doubt it's the connection that you want to share, rather it's the models (I'm guessing). You can put those in a shared module, and export them as a kind of connector function that injects the a given Mongoose instance into the models. See: Defining Mongoose Models in Separate Module.

Charles Desbiens
  • 879
  • 6
  • 14