-
Notifications
You must be signed in to change notification settings - Fork 7.3k
RangeErrors caused by removeAllListeners change in v0.7 #3425
Comments
I think this is a pretty strong argument for maintaining the v0.6 behavior. @bnoordhuis Besides the doc inconsistency, are there examples in the wild of this causing issues for people? If not, do you have a strong objection if I revert 78dc13f and make it clear in the docs that removeAllListeners also removes the listeners reference? |
Or actually, @reid, wanna just send a patch? |
@isaacs Yeah, I'll send a patch in a few hours. |
@isaacs Someone complained about it, that's why I fixed it. But if it causes more issues than it solves (which apparently it does), by all means revert it. |
Ughhh, I wish |
@TooTallNate without removeAllListeners() what is a good way to cleanup event emitter objects so they can be free'd |
When removeAllListeners is called, the listeners array is deleted to maintain compatibility with v0.6. Reverts "events: don't delete the listeners array" This reverts commit 78dc13f. Conflicts: test/simple/test-event-emitter-remove-all-listeners.js
var listeners = server.listeners("request").splice(0); ^ That's backwards compatible and works with the new behavior as well. In fact, it would be ideal if that's what EventEmitter.prototype.removeAllListeners = function(type) {
return this.listeners(type).splice(0);
} That would make everyone happy. It would keep the existing code working, and in fact you could do both in one shot now as well: var listeners = server.removeAllListeners("request"); Thoughts people? |
Or we could just get rid of the fact that .listeners() returns a mutable array :-) |
I do not agree with the reverting to the 0.6 behavior. @TooTallNate's suggesting is kinda neat. |
@piscisaureus Unfortunately, @TooTallNate's proposal keeps the array reference intact after Keeping the array reference alive breaks compatibility with a frozen API. If we had the implementation by @bnoordhuis or @TooTallNate before the API was stable, I'd prefer it. I do not believe the benefit is significant enough to break compatibility that's guaranteed by the Stability Index. The test inside pull request 3431 verifies the behavior I described in my original example above. The test fails when I change removeAllListeners to |
I'm generally in agreement with @reid on this. We advertised that the behavior of require('events') wouldn't change, and here it is clearly changed. It is clear that a compromise will not work: either the listener array is a persistent reference after removeAllListeners, or it is not. It's easy for @reid (and others) to work around in their currently-existing-in-reality programs, but they shouldn't have to; it'll be even easier to work around the other direction in programs that don't yet exist. That being said, what's the actual harm caused by not leaving the array intact? So far, the main arguments for not reverting are (a) "the docs say so", and (b) "oh, it'd be cool if you could...". For (a) we can change the docs, and for (b) we can shrug and say "Sorry, that's not how it works, do a different thing". But not to be too hasty, are there other arguments for keeping the new behavior? |
Well if we revert back to the previous behavior, then there's a chance of somebody calling That |
* V8: Upgrade to v3.11.10 * npm: Upgrade to 1.1.26 * doc: Improve cross-linking in API docs markdown (Ben Kelly) * Fix nodejs#3425: removeAllListeners should delete array (Reid Burke) * cluster: don't silently drop messages when the write queue gets big (Bert Belder) * Add Buffer.concat method (isaacs) * windows: make symlinks tolerant to forward slashes (Bert Belder) * build: Add node.d and node.1 to installer (isaacs) * cluster: rename worker.unqiueID to worker.id (Andreas Madsen) * Windows: Enable ETW events on Windows for existing DTrace probes. (Igor Zinkovsky) * test: bundle node-weak in test/gc so that it doesn't need to be downloaded (Nathan Rajlich) * Make many tests pass on Windows (Bert Belder) * Fix nodejs#3388 Support listening on file descriptors (isaacs) * Fix nodejs#3407 Add os.tmpDir() (isaacs) * Unbreak the snapshotted build on Windows (Bert Belder) * Clean up child_process.kill throws (Bert Belder) * crypto: make cipher/decipher accept buffer args (Ben Noordhuis)
Node.js 0.7.11 fixes a regression from 0.6.x that broke the phantom module used in testing. See: nodejs/node-v0.x-archive#3425
A common code pattern I see in projects that need to attach to another
http.Server
is this:The problem is that 78dc13f causes removeAllListeners to maintain the array reference returned by the listeners call, which results in new side effects: since Node v0.7, the listeners array shown above will be updated with new event listeners attached.
In Node v0.6, the call to listeners() acted like a copy, so this code would not result in a loop.
If the listeners array is copied before being used, the v0.6-style behavior can be obtained. For exmaple, see: yui/yeti@51aa577#L1R25
This is currently a problem for the dnode project, which uses Socket.io 0.8.6 that uses this pattern for handling HTTP upgrades. This was also a problem with my own code as well.
For the sake of easy upgrades from v0.6, I request for the existing behavior to be maintained.
If this request is denied, the wiki about 6-to-8 changes should be updated to reflect this behavior change: https://github.com/joyent/node/wiki/API-changes-between-v0.6-and-v0.8
The text was updated successfully, but these errors were encountered: