Permalink
Browse files

Changed Server.isConnected to use the actual state variable, fixed fi…

…reCallbacks for findAndModify to avoid duble fires, (Issue #581)
  • Loading branch information...
1 parent f8eead5 commit 631f287cf6c1e8b4af4fdb9f427778f19d3e460d @christkv christkv committed Apr 20, 2012
Showing with 83 additions and 5 deletions.
  1. +23 −4 lib/mongodb/connection/server.js
  2. +1 −1 lib/mongodb/db.js
  3. +59 −0 test/manual_tests/find_modify_break_test.js
@@ -183,7 +183,7 @@ Server.prototype.close = function(callback) {
* @ignore
*/
Server.prototype.isConnected = function() {
- return this.connectionPool != null && this.connectionPool.isConnected();
+ return this._serverState == 'connected';
}
/**
@@ -534,9 +534,28 @@ var _fireCallbackErrors = function(server, err) {
// For each key check if it's a callback that needs to be returned
for(var j = 0; j < keys.length; j++) {
var info = dbInstance._callBackStore._notReplied[keys[j]];
- if(info.connection.socketOptions.host === server.host && info.connection.socketOptions.port === server.port) {
- dbInstance._callBackStore.emit(keys[j], err, null);
- }
+ // Check if we have a chained command (findAndModify)
+ if(info && info['chained'] && Array.isArray(info['chained']) && info['chained'].length > 0) {
+ var chained = info['chained'];
+ // Only callback once and the last one is the right one
+ var finalCallback = chained.pop();
+ // console.dir(finalCallback)
+ if(info.connection.socketOptions.host === server.host && info.connection.socketOptions.port === server.port) {
+ dbInstance._callBackStore.emit(finalCallback, err, null);
+ }
+
+ // Put back the final callback to ensure we don't call all commands in the chain
+ chained.push(finalCallback);
+
+ // Remove all chained callbacks
+ for(var i = 0; i < chained.length; i++) {
+ delete dbInstance._callBackStore._notReplied[chained[i]];
+ }
+ } else {
+ if(info && info.connection.socketOptions.host === server.host && info.connection.socketOptions.port === server.port) {
+ dbInstance._callBackStore.emit(keys[j], err, null);
+ }
+ }
}
}
}
View
@@ -1350,7 +1350,7 @@ var __executeQueryCommand = function(self, db_command, options, callback) {
} else if(connection instanceof Error) {
return callback(connection);
}
-
+
// Perform reaping of any dead connection
if(self.reaperEnabled) reaper(self, self.reaperInterval, self.reaperTimeout);
@@ -0,0 +1,59 @@
+var mongodb = require("../../lib/mongodb"),
+ request = true;
+
+var db = new mongodb.Db('test_db', new mongodb.Server("127.0.0.1", 27017, {
+ auto_reconnect: false
+}), {});
+
+// listen on error
+db.on("error", function(err) {
+ console.log('open request ', request);
+ console.error('db on error');
+ console.dir(err);
+});
+
+// open connection
+db.open(function(err, client) {
+ if (err) {
+ console.error(err);
+ }
+
+ var collection = new mongodb.Collection(client, 'test_collection');
+
+ // define find and modify
+ var findAndModifyLoop = function() {
+ // mark request = true as sending mongo request
+ request = true;
+
+ console.log('findAndModify request (should not be last)');
+
+ collection.findAndModify({hello: 'world'}, [['_id', 'asc']], {$set: {hi: 'there'}},{safe:true}, function(err, object) {
+ if (err) {
+ console.warn('findAndModify response ', err.message); // returns error if no matching object found
+ } else {
+ console.log('findAndModify response', object);
+ }
+
+ // no more out standing request
+ request = false;
+
+ // on result does it again
+ findAndModifyLoop();
+ });
+ };
+
+ // start the loop
+ findAndModifyLoop();
+});
+
+db.on("error", function(err) {
+ console.log('open request ', request);
+ console.error('db on error');
+ console.dir(err);
+});
+
+db.on("close", function(err) {
+ console.log('open request ', request);
+ console.error('db on close');
+ console.dir(err);
+});

0 comments on commit 631f287

Please sign in to comment.