events: add EventEmitter.defaultMaxListeners

Class property that controls the maximum number of listeners for all
instances of EventEmitter.

Fixes #3014.

Conflicts:
	lib/events.js
This commit is contained in:
Ben Noordhuis 2012-05-04 17:45:27 +02:00 committed by isaacs
parent 2efb6cf0cf
commit cf0fa96db8
3 changed files with 53 additions and 10 deletions

View File

@ -68,9 +68,19 @@ Removes all listeners, or those of the specified event.
### emitter.setMaxListeners(n) ### emitter.setMaxListeners(n)
By default EventEmitters will print a warning if more than 10 listeners are By default EventEmitters will print a warning if more than 10 listeners are
added for a particular event. This is a useful default which helps finding memory leaks. added for a particular event. This is a useful default which helps finding
Obviously not all Emitters should be limited to 10. This function allows memory leaks. Obviously not all Emitters should be limited to 10. This function
that to be increased. Set to zero for unlimited. allows that to be increased. Set to zero for unlimited.
### EventEmitter.defaultMaxListeners
`emitter.setMaxListeners(n)` sets the maximum on a per-instance basis.
This class property lets you set it for *all* `EventEmitter` instances,
current and future, effective immediately. Use with care.
Note that `emitter.setMaxListeners(n)` still has precedence over
`EventEmitter.defaultMaxListeners`.
### emitter.listeners(event) ### emitter.listeners(event)

View File

@ -33,17 +33,18 @@ function EventEmitter() {
} }
} }
this._events = this._events || {}; this._events = this._events || {};
this._maxListeners = this._maxListeners || defaultMaxListeners; this._maxListeners = this._maxListeners || undefined;
} }
exports.EventEmitter = EventEmitter; exports.EventEmitter = EventEmitter;
// By default EventEmitters will print a warning if more than
// 10 listeners are added to it. This is a useful default which // By default EventEmitters will print a warning if more than 10 listeners are
// helps finding memory leaks. // added to it. This is a useful default which helps finding memory leaks.
// EventEmitter.defaultMaxListeners = 10;
// Obviously not all Emitters should be limited to 10. This function allows // Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited. // that to be increased. Set to zero for unlimited.
var defaultMaxListeners = 10;
EventEmitter.prototype.setMaxListeners = function(n) { EventEmitter.prototype.setMaxListeners = function(n) {
if (typeof n !== 'number' || n < 0) if (typeof n !== 'number' || n < 0)
throw TypeError('n must be a positive number'); throw TypeError('n must be a positive number');
@ -150,7 +151,13 @@ EventEmitter.prototype.addListener = function(type, listener) {
// Check for listener leak // Check for listener leak
if (typeof this._events[type] === 'object' && !this._events[type].warned) { if (typeof this._events[type] === 'object' && !this._events[type].warned) {
m = this._maxListeners; var m;
if (this._maxListeners !== undefined) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) { if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true; this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' + console.error('(node) warning: possible EventEmitter memory ' +

View File

@ -56,3 +56,29 @@ for (var i = 0; i < 1000; i++) {
} }
assert.ok(!e._events['unlimited'].hasOwnProperty('warned')); assert.ok(!e._events['unlimited'].hasOwnProperty('warned'));
// process-wide
events.EventEmitter.defaultMaxListeners = 42;
e = new events.EventEmitter();
for (var i = 0; i < 42; ++i) {
e.on('fortytwo', function() {});
}
assert.ok(!e._events['fortytwo'].hasOwnProperty('warned'));
e.on('fortytwo', function() {});
assert.ok(e._events['fortytwo'].hasOwnProperty('warned'));
delete e._events['fortytwo'].warned;
events.EventEmitter.defaultMaxListeners = 44;
e.on('fortytwo', function() {});
assert.ok(!e._events['fortytwo'].hasOwnProperty('warned'));
e.on('fortytwo', function() {});
assert.ok(e._events['fortytwo'].hasOwnProperty('warned'));
// but _maxListeners still has precedence over defaultMaxListeners
events.EventEmitter.defaultMaxListeners = 42;
e = new events.EventEmitter();
e.setMaxListeners(1);
e.on('uno', function() {});
assert.ok(!e._events['uno'].hasOwnProperty('warned'));
e.on('uno', function() {});
assert.ok(e._events['uno'].hasOwnProperty('warned'));