guileen/node-mongoskin — Issue #33: repeated connect failures result in listener proliferation and multiple callbacks
Author: jlfaber
Created: 2012-02-15 03:20:26+00:00
State: open

The "open" listeners for collection, cursor, and db are all registered using EventEmitter.addListener instead of EventEmitter.once. If the first open attempt errors out, the listener callback is properly called with the error, but the callback remains registered. A second attempt will add another listener, but if that errors out as well, both the new AND the original callbacks will be invoked.

Here's a program that demonstrates the issue:

```javascript
var mongo = require('mongoskin');
var db = mongo.db('localhost:27017/bogus');
var coll = db.collection('does_not_matter');

var doQuery = function () {
console.error();
console.error('in doQuery');
coll.find( {}, function( error, results ) {
if (error) {
console.error('got an error:',error);
return;
}
console.error(results);
});
};

setInterval( doQuery, 1000 );
```

Since this is calling a collection method, the problem is exacerbated by the fact that both the collection and the underlying db have callbacks. So the first error invokes the callback method once, the second error invokes it four times, the third nine, and so on.

I think the solution to this is to use EventEmitter.once instead of EventEmitter.addListener. This will remove the callback once its fired. I'm creating a pull request with that modification.