node js cluster mongoose connection - node.js

I am using nodejs built in cluster module in my application mongodb( not sharded) used for
storage in each cluster(worker) connection is made using mongoose.createConnection method and closes after inserting data.
But what i am expecting is whenever a request is made it opens connection to the db and process request and close the connection.
But what i noticed that when i checking the mongodb log still open connection and its count sligtly larger than no of processor/(cluster nodes).
and i put poolSize:1,autreconect:false still some connections are not closing even after close() method is called.
my observations are when connection error happends the connection is not closed
Please help me
I am using following script to get the connection .
module.exports.getDb = function () {
var dburl = 'mongodb://localhost/DB';
db = mongoose.createConnection(dburl, {
server: {
socketOptions: {
keepAlive: 1,
connectTimeoutMS: 30000
},
auto_reconnect: false,
poolSize: 1
}
}, function (err) {
console.log(err)
});
db.on('error', function (err) {
console.log(err + " this is error");
db.close();
});
return db;
}
and i close the conneciton using db.close() in the end of evey query callback.

Are you looking for something like this?
db.connection.on('error', function (e) {
console.log(e + " this is error");
db.close();
});
For my API server, I wrote a plugin for Hapi to handle this. Take a look, it might help you.
'use strict';
var bluebird = require('bluebird');
var mongoose = bluebird.promisifyAll(require('mongoose'));
exports.register = function(plugin, options, next) {
mongoose.connect(options.mongo.uri, options.mongo.options, function (e) {
if (e) {
plugin.log(['error', 'database', 'mongodb'], 'Unable to connect to MongoDB: ' + e.message);
process.exit();
}
mongoose.connection.once('open', function () {
plugin.log(['info', 'database', 'mongodb'], 'Connected to MongoDB # ' + options.mongo.uri);
});
mongoose.connection.on('connected', function () {
plugin.log(['info', 'database', 'mongodb'], 'Connected to MongoDB # ' + options.mongo.uri);
});
mongoose.connection.on('error', function (e) {
plugin.log(['error', 'database', 'mongodb'], 'MongoDB ' + e.message);
});
mongoose.connection.on('disconnected', function () {
plugin.log(['warn', 'database', 'mongodb'], 'MongoDB was disconnected');
});
});
return next();
};
exports.register.attributes = {
name: 'mongoose',
version: '1.0.0'
};

Related

How to fix issue with sql query execution using call back

I am having problem with sql query execution using callback, I never worked on the node.js, so looking for some guidance and get going.
Tried with having database connection in same file, but unable to execute when having the database connection in another file.
DatabaseManager.js
var Tedious = require('tedious');
var Connection = Tedious.Connection;
var Request = Tedious.Request;
function connect(cb) {
var config = {
userName: 'dddff',
password: 'fsfdsf',
server: '12345.database.windows.net',
options:
{
database: '12345',
encrypt: true
}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
if (err) {
console.log(err);
return;
}
console.log('CONNECTED TO DATABASE');
cb(connection);
});
}
module.exports = connect;
app.js
var connect = require('./DatabaseManager');
bot.dialog('profileDialog', (session) => {
session.send('Hello Message', session.message.text);
console.log('Creating a connection');
connect(function(connection) {
console.log('Reading rows from the Table.');
// Execute queries here and how to frame the syntax here?
connection.query("select FNAME from StudentProfile where ID=1"),
function(err, result, fields) {
if (err) throw err;
console.log(result);
}
});
})
I expect the output of select statement result on the console.

MongoClient.connect doesn't execute callback function

I'm relatively new to node.js. Trying to test connection to mongodb using mocha framework and mongodb driver.
Node.js version - 6.11.3
Mongodb driver version - 2.2.31
Mondodb version - 3.4.7
Here's my js file:
var should = require("should");
var expect = require('chai').expect;
var cfg = require('../config');
var uri = cfg.mongouri;
var MongoClient = require('mongodb').MongoClient, Logger =
require('mongodb').Logger;
Logger.setLevel('debug');
describe("mongoconnection", function () {
describe("fetch data", function () {
it("should fetch data from db", function (done) {
MongoClient.connect(uri,function(err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
}
db.close();
});
done();
});
});
});
However, this part of the code
function(err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
}
db.close();
}
never gets executed and I can't establish connection, e.g. I don't get neither console log nor exception.
Debug information:
[DEBUG-Connection:9352] 1506430786041 creating connection 0 with options [{"host":HOST,"port":PORT,"size":5,"keepAlive":true,"keepAliveInitialDelay":300000,"noDelay":true,"connectionTimeout":30000,"socketTimeout":360000,"ssl":true,"ca":null,"crl":null,"cert":null,"rejectUnauthorized":false,"promoteLongs":true,"promoteValues":true,"promoteBuffers":false,"checkServerIdentity":true}] { type: 'debug',
message: 'creating connection 0 with options [{"host":HOST,"port":PORT,"size":5,"keepAlive":true,"keepAliveInitialDelay":300000,"noDelay":true,"connectionTimeout":30000,"socketTimeout":360000,"ssl":true,"ca":null,"crl":null,"cert":null,"rejectUnauthorized":false,"promoteLongs":true,"promoteValues":true,"promoteBuffers":false,"checkServerIdentity":true}]',
className: 'Connection',
pid: 9352,
date: 1506430786041 }
also already checked that connection string is correct and I can establish connection to it via another app (groovy script executed in SoapUI).
I am stuck at this point, can someone please help me with this, thanks in advance.
You are calling done() from Mocha outside of the async callback from the MongoClient.connect. So done() is called before it can even connect to the db.
Change your code to this:
it("should fetch data from db", function (done) {
MongoClient.connect(uri,function(err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
}
db.close();
done();
});
});

How to handle MongoDB Client connection error after it has been cached Mongo shuts down ?

I have created a mongodb native connection and saved it and then using findOne to query a document.
const Promise = require("bluebird");
const MongoClient = require('mongodb').MongoClient;
let mongoDB = undefined;
const getCollection = (collName) => {
if (mongoDB) {
return Promise.resolve(mongoDB.collection(collName));
} else {
return MongoClient.connect(EXT_CONFS.MONGODB_URL)
.then(db => {
mongoDB = db;
return Promise.resolve(mongoDB.collection(collName));
}).catch(e => {
console.error('Error in MongoDb connection');
});
}
};
const findOne = (collName, filter, options) => {
return getCollection(collName)
.then(collection => {
return collection.findOne(filter, options);
})
.then(doc => {
return Promise.resolve(doc);
}).catch(e => {
console.error(e);
return Promise.reject(e);
});
};
Now this all works fine, but if Mongo ShutsDown / Fails after db client is cached, There is no way to handle error. Error never goes to any catch handler :
console.error('Error in MongoDb connection');
or
console.error(e);
I even tried events :
mongoDB.on('connecting', function () {
console.log('connecting');
});
mongoDB.on('timeout', function (error) {
console.log('timeout!');
});
mongoDB.on('close', function (error) {
console.log('close!');
});
mongoDB.on('error', function (error) {
console.error('Error in MongoDb connection: ' + error);
});
mongoDB.on('connected', function () {
console.log('connected!');
});
mongoDB.on('connection', function () {
console.log('connected!');
});
mongoDB.on('connect', function () {
console.log('connected!');
});
mongoDB.once('open', function () {
console.log('connection open');
});
mongoDB.on('reconnected', function () {
console.log('reconnected');
});
mongoDB.on('disconnected', function () {
console.log('disconnected');
});
but no success still. Using NodeJS 4.5.0, MongoDB-Native driver 2.2.24
You should do something like console.error('Failed to connect to mongodb ',e); you are not outputting the error.
Also some events provide an additional parameter and you are outputting those either. In case of failing to connect to an mongodb server, your application should just notify you it's not the best approach to handle mongodb server start/restart from your application use daemons such as systemd or other process monitoring.
Some events are there to just notify the application that connection was lost or an reconnection is attempted, its up to you to handle what is going to be done when those events are emitted.
You can for example attempt to check mongodb status when an disconnect event is emitted an recreate connection object.
You could wrap the connect statement in a try-catch block.

Mongoose - Save doesnt work when am connecting to mongodb running in different server

When am trying to save a document in a collection or find the list of collections in mongodb running remotely doesnt work but works when am connecting to mongo db locally. save doesnt show if it throwed an error or it was successful.
Your help is appreciated.
below is my code
var mongoose = require('mongoose');
var dbName = 'OST';
var connectionString = 'mongodb://vm-1b98-f53f.nam.nsroot.net:32017/OST?ssl=true&sslverifycertificate=false';
mongoose.connect(connectionString);
mongoose.connection.on('error', function (err) {
console.log('Mongoose default connection error: ' + err);
});
mongoose.connection.on('connected', function () {
console.log('Mongoose default connection open to ' + connectionString);
var Region = require('./Region.js');
var r = new Region({ NodeID: 8687, RegionName: 'EMEA' });
r.save(function (err, regionObj) {
if (err) {
console.log('error');
throw err;
} else {
console.log('saved successfully:', regionObj);
}
});
mongoose.connection.db.collectionNames(function (error, names) {
if (error) {
console.log(error);
} else {
names.map(function (cname) {
console.log(cname.name);
});
}
});
});
process.on('SIGINT', function () {
mongoose.connection.close(function () {
process.exit(0);
});
});

Mongoose connection events with createConnection

I moved away from using the default connection to a explicitly defined connection.
My code is working except that none of the event handlers which track the state of my mongo connection are firing.
the events used to fire when I was using default mongoose connection. (mongoose.connect).
var mongoose = require('mongoose'),
logger = require('../logger'),
config = require('../config');
mongoose.connection.on('connecting', function(){
logger.info("trying to establish a connection to mongo");
});
mongoose.connection.on('connected', function() {
logger.info("connection established successfully");
});
mongoose.connection.on('error', function(err) {
logger.error('connection to mongo failed ' + err);
});
mongoose.connection.on('disconnected', function() {
logger.log('mongo db connection closed');
})
var gracefulExit = function() {
db.close(function(){
logger.log("mongoose connection with db " + server + 'is closing');
process.exit(0);
});
};
process.on('SIGNT', gracefulExit).on('SIGTERM', gracefulExit);
var db = mongoose.createConnection(config.get('DB_URL'));
module.exports = db;
the problem with the code is
None of the event handlers are firing.
Even the process events on SIGNT and SIGTERM are not firing.
I also tried
var db = mongoose.createConnection(config.get('DB_URL'));
db.on('connecting', function(){
logger.info("trying to establish a connection to mongo");
});
but this also doesn't fire.
i also faced with this problem,
and finally i solved it, after understood that the connect() / createConnection() execute before i declare the event handlers.
so the my open or connected events handlers will never called again.
so by declare them first and just after trying to connect - will solve your problem!
for example:
try {
mongoose.connection
.on('error', err => {
console.error(err);
})
.on('open', err => {
console.log(`DB connected`);
})
await mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });
} catch (error) {
handleError(error);
}
This snippet blow work fine for me
const connection = mongoose.createConnection(`mongodb://${process.env.MONGO_URI}`);
connection.on('connected', () => {
console.log('connected to mongodb');
});
connection.on('disconnected', () => {
console.log('connection disconnected');
});
I just stumbled over this issue myself and found that I needed to set up the EventListeners before the actual connection to the database like so (with async/await):
export class Database {
public static connect( databaseCredentials: string ) {
return new Promise( async resolve => {
// ! The `EventListeners` is setup here.
mongoose.connection.on( "connected", () => {
logger.info( "Database has connected successfully." );
});
mongoose.connection.on( "error", (error) => {
logger.error( " Obs! There was an unexpected error connecting to the database.", error );
});
// ! The acutal connection to the database happens here.
await mongoose.connect( databaseCredentials, {
useNewUrlParser: true,
useUnifiedTopology: true,
keepAlive: true,
reconnectInterval: 500,
connectTimeoutMS: 10000,
});
resolve();
});
}
}
This should also work the same way with mongoose.createConnections.
This will yield the result (if successful):
{ message: 'Database has connected successfully.',
level: 'info',
timestamp: '2019-10-11T15:17:16.616Z' }
I just wanted to chip in and give my solution to the problem at hand and give a full example implementation of the code, as the above answers didn't explain in which order you needed to listen for the events. If you were to put the mongoose.connection.on() below the await.mongoose.connect(), this would not yield any response from the EventListeners.
Edit: Typos
try:
mongoose.connection.on('open', function() {
logger.info("database is ready now");
});
also temporary remove .close()

Resources