alexguan/node-zookeeper-client — pull request #19 by sudowork (2014-03-25 21:56:19+00:00)
Title: Fix duplicate watchers from being added

Based on the existing code for `WatcherManager.js`, it seems like adding a duplicate watcher should not be allowed. However, the current check for `watchers[path].listeners('notification').indexOf(watcher) === -1` will never be false. This is because [`EventEmitter`](https://github.com/joyent/node/blob/v0.10.26-release/lib/events.js#L169) ends up wrapping the listener before adding it if `once()` was used.

Here's a contrived test based on the `examples/get.js` example:

```javascript
var zookeeper = require('./index.js');
var client = zookeeper.createClient(process.argv[2], { retries : 2 });
var path = process.argv[3];

function watcher(event) {
console.log('Fire me once: %s', event);
getData(client, path);
}

function getData(client, path) {
client.getData(
path,
watcher,
function (error, data, stat) {
if (error) {
console.log('Error occurred when getting data: %s.', error);
return;
}

console.log(
'Node: %s has data: %s, version: %d',
path,
data ? data.toString() : undefined,
stat.version
);
}
);
}

client.once('connected', function () {
console.log('Connected to ZooKeeper.');
getData(client, path);
// @NOTE: this should not register a second watcher
getData(client, path);
});

client.connect();
```

Output before the patch:
```
$ node test.js localhost:2181 /test
Connected to ZooKeeper.
Node: /test has data: hi, version: 5
Node: /test has data: hi, version: 5
Fire me once: NODE_DATA_CHANGED[3]@/test
Fire me once: NODE_DATA_CHANGED[3]@/test
Node: /test has data: hi, version: 6
Node: /test has data: hi, version: 6
```

Output after the patch:
```
$ node test.js localhost:2181 /test
Connected to ZooKeeper.
Node: /test has data: hi, version: 6
Node: /test has data: hi, version: 6
Fire me once: NODE_DATA_CHANGED[3]@/test
Node: /test has data: hi, version: 7
```