What is the correct way to open, manage and close database connection object (nodejs driver) in a script that does conditional logic based on query results

48 views
Skip to first unread message

Mindaugas Bernatavičius

unread,
Sep 15, 2017, 3:07:42 AM9/15/17
to mongodb-user
Hi,

I have a script that does some conditional logic - a simplified snippet below.
I because of the async nature of the nodejs driver, I have some difficulties, like
destruction of connections when updates/inserts are still running. This resulting in

MongoError: topology was destroyed

How do I correctly manage the database connection in such a script? 
How can I close connection once but not mid-execution?
Should I return the database connection from MongoClient object rather than using a callback?
Any general guidance on how to structure the code more appropriately would really help.
Thanks! 

#!/usr/bin/env node

// Initialization parameters
var http = require('http');
var MongoClient = require('mongodb').MongoClient;

// polluterTenantId needs to be obtained from DB.
function GetTenantIDFromName(exp, db){
   let tID
= db.collection('Tenant').find({ "Name": { $regex: rxPtt }}, {"_id": 1}).toArray();
   
return tID;
}

MongoClient.connect(url, function(err, db) {
   
if(err) throw err;
    let tID
= GetTenantIDFromName(tenant, db);
 
    tID
.then(function(polluterTenantId){
       
if (del !== true && polluterTenantId.length > 1){
           
throw "There was more than 1 tenant";
            db
.close(function(){ console.log("Close connection"); });
       
} else if (del !== true && polluterTenantId.length < 1) {
           
throw "No tenats matched the pattern" + tenant + ".";
            db
.close(function(){ console.log("Close connection"); });
       
} else {
           
// some more inserts / finds / collection creations
       
}
   
});
   
    db
.close(function(){ console.log("Close connection"); });
});

Kevin Adistambha

unread,
Sep 26, 2017, 10:56:59 PM9/26/17
to mongodb-user

Hi

In your script as posted, you have some undefined variables that I assume was defined in some other parts of the code (e.g. url, rxPtt, del).

However, ignoring all the undefined variables, there are a couple of things that I can see in the code:

  1. throw will stop function execution (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw), so the db.close(...) after throw will never be executed. This can be confirmed by running eslint on the code snippet (it will output warning: Unreachable code on those lines).
  2. you have a db.close() outside of the tID.then(...) but immediately follows it, which means that the code is closing the database before the query have a chance to come back.

I believe the message topology was destroyed was caused by #2 above. To verify this, you could put some identifying numbers to the Close connection strings so that you can identify precisely which db.close() was executed and in what order. For example, you can change the three Close connection strings above to Close connection 1, Close connection 2, and Close connection 3 from top to bottom. I believe you will first see Close connection 3 string printed to the console before the topology was destroyed message.

Best regards,
Kevin

Reply all
Reply to author
Forward
0 new messages