Reputation: 2908
In Node.js, I have (briefly) this script:
var http = require('http');
var XmlStream = require('xml-stream');
var mongo = require('mongodb');
var tims = { ... };
var db = new mongo.Db('tims', new mongo.Server("127.0.0.1", 27017, {}), {w: 1});
db.open(function(e, db) {
var req = http.get({
host: tims.uri,
path: '/xml/'+tims.database+tims.services.database
}).on('response', function(res) {
res.setEncoding('utf8');
cProjects = db.collection("projects");
var xml = new XmlStream(res);
xml.on('updateElement: Tims ProjectID', function(project) {
// console.log(project.$text+' - '+project.$.title);
cProjects.update({project_id: project.$text}, {project_id: project.$text, title: project.$.title}, {upsert:true}, function(err, result) {
console.log('result: '+result);
});
});
xml.on('end', function(data) {
db.close();
});
});
});
I am using a Node.js package called xml-stream that pieces together response chunks from Node to get valid XML before processing. My problem: if I leave out
xml.on('end', function(data) {
db.close();
});
my connection never closes and the console just hangs. The upside is that console.log('result: '+result);
writes to the console and I can see that my data was committed successfully. So if I leave in the end
event and close the DB once all XML has been processed, the Node instance terminates before console.log('result: '+result)
is written.
I am a newbie to both MongoDB and Node.js, so I was curious what the best practice is here for confirmation, or perhaps a simple pointing out of what I'm doing wrong.
Thanks for the help.
Upvotes: 2
Views: 423
Reputation: 311855
Looks like the 'end'
event is occurring before all the update
callbacks have completed. So you need to rework your code a bit to keep track of the number of updates still pending and only call db.close()
once both the 'end'
event has fired and all the pending updates have completed.
So something like this:
db.open(function(e, db) {
var req = http.get({
host: tims.uri,
path: '/xml/'+tims.database+tims.services.database
}).on('response', function(res) {
res.setEncoding('utf8');
cProjects = db.collection("projects");
var xml = new XmlStream(res);
var end = false;
var pending = 0;
xml.on('updateElement: Tims ProjectID', function(project) {
// console.log(project.$text+' - '+project.$.title);
++pending;
cProjects.update({project_id: project.$text}, {project_id: project.$text, title: project.$.title}, {upsert:true}, function(err, result) {
console.log('result: '+result);
if (--pending === 0 && end) {
db.close();
}
});
});
xml.on('end', function(data) {
end = true;
});
});
});
Upvotes: 1