In my node js program, After opening mongo connection I trying to run certain query and finally trying to close connection.
group.find({group_name: "music"}, function (doc) {
// do your stuff
console.log(doc);
mongoose.connection.close();
});
But while I trying to see mongotop log, after closing the connection, its still show as connected
Here finananceManagement is the the database, which I tried to connect, If I restart the mongo service it will disapper from the log, help me to resolve this issue
Related
I am trying to use MongoDB for a REST API project. Yesterday, the db worked fine and it showed up in command prompt. Now, when I run db in my mongo terminal, my database does not show up. It even says that it connected to the MongoDB when I run my server which uses this code:
const connectWithRetry = () => {
console.log('MongoDB connection with retry')
mongoose.connect("mongodb://localhost:27017/rest-tutorial", options).then(()=>{
console.log('MongoDB is connected')
}).catch(err=>{
console.log('MongoDB connection unsuccessful, retry after 5 seconds. ', ++count);
setTimeout(connectWithRetry, 5000)
})
};
I'm new to this so I am kind of unsure what to do. The code works fine and when I register new users and send data to the database, I get my desired output. However, I am unable to see the stored data in command line. What can I do?
EDIT AS REQUESTED
mongo commands run:
db
test
show collections
(nothing shows up even though I submitted data. This is also the wrong db)
To give some context: I have a Java client application that communicates high scores to a Node.js backend via sockets. All of those aspects are working correctly. The issue is that, when I run the object.save() method, it doesn't save the object in the db. It also doesn't throw any errors, and doesn't even console.log() like it's meant to.
Here is my code.
socket.on('setScore',function(data){
var workingScore = new Score(data);
console.log("WorkingScore:");
console.log(workingScore);
workingScore.save(function(err){
console.log("MADE IT THIS FAR");
if(err)
{console.log(err)}
else
{console.log("Saved!")}
})
});
None of the three console.log() handlers fire within the workingScore.save() callback.
When I create the server, I connect to my mongodb database, and this appears to work, as the mongod console shows a new connection when the server is started. The code for that is:
mongoose.createConnection('localhost','LeaderboardDB');
When I open mongo from terminal and do use LeaderboardDB then show collections nothing comes up.
Is it a good practice in nodejs to open mongodb connection per each request, and close it in the callback?
app.get('/some_route', function(){
MongoClient.connect(url,function(err, db){
//some db query with callback
db.collection("some_collection").findOne(doc, function(err,item){
if(err){
res.send(err);
//close db connection
db.close();
}else{
//do something with item
res.send(item);
//close db connection
db.close();
}
});
});
Some said that opening/closing mongodb connection on each request isn't necessary, since once opened, a pool of connections can be shared.
The question is how to maintain and share that pool? Is mongoose doing that automatically already?
Especially, on mongodb timeout or disconnect, does it need to be reconnected?
I find contradictory answers here close mongodb connection per request or not
Almost all the online doc nodejs mongodb native driver and example code I read, a db.open() is paired with db.close() somewhere in the callback.
Because if a pool of connection is shared, one might code
According to christkv's answer, one might code:
var p_db=null;
var c_opt = {server:{auto_reconnect:true}};
app.get('/some_route', function(){
//pseudo code
if (!p_db){
MongoClient.connect(url, c_opt, function(err,db){
p_db = db;
p_db.collection("some_collection").findOne(doc, function(err,item){
if(err){
res.send(err);
}else{
//do something with item
res.send(item);
}
});
});
}else {
p_db.collection("some_collection").findOne(doc, function(err,item){
if(err){
res.send(err);
}else{
//do something with item
res.send(item);
}
});
});
According to a major contributor to the driver source, It's best to connect to the database at startup and keep reusing that same connection for each request.
The mongodb native driver has a connection pool which it maintains internally and currently defaults to a maximum of 5 open connections. You can configure the maximum number of connections via the maxPoolSize option. You can also configure the connection to auto reconnect with the auto_reconnect option.
See the documentation here
You don't have to do anything to reconnect as the driver will attempt to reconnect on failure. While it waits for the reconnect to happen it will buffer all operations happening in between and replay them once the connection is up. If you want to control this yourself you can listen to the "close" event on the db instance and handle reconnection manually. On reconnect the db object will still be viable as a db is really just a wrapper around the shared connection pool and does not contain it's own separate connection logic.
I am trying to use node.js with mongodb and following the tutorial at http://howtonode.org/express-mongodb
The code for opening the connection is
ArticleProvider = function(host, port) {
this.db= new Db('node-mongo-blog', new Server(host, port, {auto_reconnect: true}, {}));
this.db.open(function(){});
};
However i cannot see any connections being closed.
But when i see the logs on the mongo console, i can see that are connections which open and they close after some time.
Does the connection close automatically? Will it be a problem when a large no of clients try to access the server? Where should the connection be closed?
Thanks
Tuco
In that example application, only a single ArticleProvider object is created for the application to share when serving requests. That object's constructor opens a db connection that won't be closed until the application terminates (which is fine).
So what you should see is that you get a new mongo connection each time you start your app, but no additional connections made no matter how many clients access the server. And shortly after you terminate your app you should see its connection disappear on the mongo side.
node-mongodb-native provides a close method for Db objects and you can close your connection when you are finished by calling it.
var that = this;
this.db.open(function(){
// do db work here
// close the connection
that.db.close();
});
If you don't close your connection, event loop keeps the connection open and your process doesn't exit. If you are building a web server where your process will not be terminated, it's not necessary for you to close the connection.
A better reference for node-mongodb-native can be found on https://github.com/mongodb/node-mongodb-native.
Remember to put the db.close in the last callback that gets executed so the connection is open until all callbacks are finished. Otherwise, it gives an error like
/usr/local/lib/node_modules/mongodb/lib/utils.js:97
process.nextTick(function() { throw err; });
^
Error
at Error.MongoError (/usr/local/lib/node_modules/mongodb/node_modules/mongodb-core/lib/error.js:13:17)
at Server.destroy (/usr/local/lib/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:629:47)
at Server.close (/usr/local/lib/node_modules/mongodb/lib/server.js:344:17)
at Db.close (/usr/local/lib/node_modules/mongodb/lib/db.js:267:19)
I've been evaluating Mongoose (an ORM for node.js which uses MongoDB for persistent storage).
What I'd like to do is make sure that the app can run when the DB is not up when the app starts, and also handles the DB going down intelligently.
Currently my test app which does not work in either case does this:
var mongoose_connection = mongoose.createConnection(DATABASE_URL, {server:{poolSize:4}});
Then I use that connection when making Models.
In the case when the DB is down at the start of the app then any save() calls on instances silently fail with no error. If the DB comes back up they never get written.
So I would need to detect that the connection never happened and have the app be able to tell that at runtime so that I can handle it somehow.
When the DB goes down after the app has started though the save() calls still do not cause errors but they are queued and the written when the DB comes back.
That seems fine except I'd like to hook into the API to get events when the DB is down and to query how many save's are queued. At some point I might have so many queued events that I would want to just stop making new ones and have the app back off.
Case #1: db is down on app startup. there is a minor bug preventing this use case that I'm fixing now. However, here is the work-around:
var db = mongoose.createConnection();
db.on('error', function (err) {
if (err) // couldn't connect
// hack the driver to allow re-opening after initial network error
db.db.close();
// retry if desired
connect();
});
function connect () {
db.open('localhost', 'dbname');
}
connect();
https://gist.github.com/2878607
An ugly but working gist. First shutdown mongo, then run this gist.
Notice the connection failures.
Then start mongo and see all of the queued up inserts complete and dumped to the console.
Writes and finds will begin.
Shutdown mongo, notice that the inserts and finds are being attempted but no callbacks are executed.
Restart mongo. Notice all of the queued inserts and finds are completed.
If you would rather fail all the requests to the server when the db is down the native driver does emit the reconnect event which can be sensed in a middleware.
This works and emits the reconnect event fine (mongodb native driver 1.3.23)
mongoose.connection.db.on('reconnect', function (ref) {
connected=true;
console.log('reconnect to mongo server.');
});
So my dbconnection middleware looks for connected/error/reconnect
(some of the events are redundant but does not harm !)
PS. the initial connect failure needs to still be handled by a retry as
aaronheckmann's answer above.
mongoose.connection.on('open', function (ref) {
connected=true;
console.log('open connection to mongo server.');
});
mongoose.connection.on('connected', function (ref) {
connected=true;
console.log('connected to mongo server.');
});
mongoose.connection.on('disconnected', function (ref) {
connected=false;
console.log('disconnected from mongo server.');
});
mongoose.connection.on('close', function (ref) {
connected=false;
console.log('close connection to mongo server');
});
mongoose.connection.on('error', function (err) {
connected=false;
console.log('error connection to mongo server!');
console.log(err);
});
mongoose.connection.db.on('reconnect', function (ref) {
connected=true;
console.log('reconnect to mongo server.');
});