I have a one-shot Node script that makes some changes to a MongoDB database on MongoLab. However, once it finishes, it never exits the event loop (I always have to ctrl+C it), no matter how much db.close() and db.logout() calling I do.
What's strange is, if I start a local running instance of mongod and connect to that, the script finishes fine, but the remote connection just never ends.
Here is a short version of my script that still has the issue (taking the URL to the server on the command line). What's going on?
var mongodb = require("mongodb");
function onSuccess(cb){
return function(err) {
if (err) {
console.error(err)
} else {
cb.apply(this,Array.prototype.slice.call(arguments,1))
}
}
}
console.log("Connecting to "+process.argv[2]+' ...');
mongodb.MongoClient.connect(process.argv[2],onSuccess(function(db){
console.log("Connected.");
db.logout(onSuccess(function(logoutResult){
db.close(onSuccess(function(closeResult){
console.log("All finished. Can has prompt return nao?")
}));
}));
}));
Just tried the code with driver version 1.2.7/1.2.8 and the newest 1.2.9 against mongolab and it works correctly. So more likely its a weird combination of driver/os/node version that's causing this. I suggest upgrade your node and driver to the latest version and try again.
I suspect it has to do with the way you have defined your closures but I cannot quite put my finger on it.
For what is worth, below is the approach that I use and this does close the connection as expected:
MongoClient.connect(dbUrl, function(err, db) {
if(err) return callback(err);
var collection = db.collection(dbCollection);
collection.find().toArray(function(err, items){
db.close()
if(err) return callback(err);
callback(null, items);
});
});
You can find a full example here: https://github.com/hectorcorrea/mongoDbSample
Related
I am new to Node world, but have some information of callbacks and Promises.
So just made a small code to get the data from the Redis and printing it to the console.
Now the code below is working pretty nice but it never returns it. Means that when I runs it using the node command, say test.js is the name of the file then it executes and returns me the value from the Redis server but never comes back to prompt. Please see the pic.Why is it so, what we have to do to make it return.
var redis = require("redis");
var client = redis.createClient(6379, "localhost");
var Promise = require("bluebird");
client.get("key1", function(err, result){
if(err)
throw err;
console.log(result);
});
You can close the process. Check if you have to close redis connection first.
client.get("key1", function(err, result){
if(err)
throw err;
console.log(result);
process.exit(0);
});
So i am very new to mongodb and i wish to use it in my application. Now i HATE redundant code but reading up on how to use mongodb with node.js it seems that there is a pattern where you always have to connect before making any CRUD operation.
Example from the offical documentation:
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
db.close();
});
});
My question is. is it possible to make a middleware that keeps the connection open so you only has to call insertDocument (in the above example) ?
Yea of course, just keep the db variable around until you don't need it any longer - then call close()
var mdb;
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
mdb = db;
insertDocument(mdb, function() {
// ...
});
});
// do other stuff with mdb
You can also look into using Mongoose as you mentioned middleware.
The connection is only opened once (on the global scope) and then you can use it throughout the app.
I'm new with Couchbase and trying to use the couchbase module 1.2.1, the connection to the DB seems to work fine, but the get and getMulti operations are failing and the error I'm getting is "Operation timed out".
I tried to increase the timeout, but it didn't help.
var db = new couchbase.Connection({ host:'localhost:8091', bucket:'beer-sample'},
function(err){
if (err){
throw err; // not getting here
}
});
db.get("id", function(err, result) {
if (!err && result){ // getting error
req.id = result;
}
});
What can be the problem?
You should try to reinstall Couchbase Server and try again using a host of 127.0.0.1:8091.
What version of Couchbase Server, and what platform/architecture you are using would also be helpful to know.
My goal is to have integration test that tests a Node Module which saves values in the redis. Here is the test:
require('coffee-script');
var should = require('should')
, redis = require('redis')
, async = require('async')
, Domain = require('../index');
async.series([
function(callback){
db = redis.createClient();
callback(null,'zero');
},
function(callback){
db.flushdb( function (err, didSucceed) {
if(err){
console.log('error: ' + err.message);
callback(err, 'one');
}
});
callback(null, 'one');
},
function(callback){
should.exist(Domain);
domain = new Domain({'attOne':1, 'attTwo':2, 'id':1});
domain.should.have.property('save');
domain.should.have.property('attOne');
domain.should.have.property('attTwo');
domain.save.should.be.an.instanceof(Function);
callback(null, 'two');
},
function(){
db.end();
}
],
function(err, results){
if(err){
console.log('error encountered: ' + err.message);
db.end();
}
console.log('All tests passed');
}
);
With this test, the problem is that the redis connection is closed before the redis flushes the the database(If i remove the db.end() at all, the test hangs but the redis db is flushed). Apparently, the async.series is not working as i expect it where every function is run before the next one in a serial order or i am misunderstanding? how to ensure this test executes in serial flow so redis connection is not closed before the flush? ...any recommendations of any libraries/frameworks that could help me on what i am trying to accomplish here? Thank You
To end the connection and stop the hanging, use client.quit() or client.end() at proper place.
For example, put this at the end of the codes:
//...
setTimeout(function(){ client.quit(); }, 3000);
// 3000 means wait 3 seconds and quit the redis connection
client.unref() is another experimental function can do the job.
Refers to : doc
well, the issue is that the callback in the redis hash commands(i.e. flushdb, hgetall ) doesn't stop the particular async process making it hang. I am not sure whether the 'async' module isn't it stoping properly or the 'redis' module has something different that prohibits 'async' to close that process....if you know the answer, please, share.
The solution was 'mocha' test framework. After installing(i.e npm install mocha) and then running 'mocha test/mytest.js', it would exit without any changes to the above code...not even formatting according to Mocha framework, it runs the test and exits nicely. At the same time, it would hang if run with 'node test/mytest.js'....the mystery of why so still remains:)
I hope this helps...It's time for Mocha now:)
I am learning and trying simple example using node.js and mongoskin. here is my function below
Problem following function is, if the mongodb server is disconnected then also I get the "err=null" hence not able catch connection error. If I restart node.js server (while mongoDB server is still disconnected) I get error as
"[Error: failed to connect to [server-aa070:27017]]"
// Process messages from client
app.post('/send', function(req, res){
var message = {
id: i++,
nickname: req.param('nickname', 'Anonymous'),
text: req.param('text', ''),
created_at: new Date()
};
conn.chat_log.insert(message, function(err) {
if(err!==null){
console.log(err);
}
else {
console.log(message);
console.log(err);
}
});
res.json({status: 'ok'});
});
I'm new to node.js and mongodb, but why are you using if(err!==null) rather than if(err)? If I'm understanding correctly, wouldn't this solve your problem?
Don't know about mongoskin, but for the node-mongo-native driver (the driver that mongoskin is built on), the author said:
Note that there's no reason to pass a callback to the insert or update
commands unless you use the safe:true option. If you don't specify
safe:true, then your callback will be called immediately.