Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Print error when EventEmitters get too many listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Jan 1, 2011
1 parent 5b81897 commit bdb1464
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
8 changes: 8 additions & 0 deletions doc/api/events.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ Remove a listener from the listener array for the specified event.
Removes all listeners from the listener array for the specified event.


#### emitter.setMaxListeners(n)

By default EventEmitters will print a warning if more than 10 listeners are
added to it. This is a useful default which helps finding memory leaks.
Obviously not all Emitters should be limited to 10. This function allows
that to be increased. Set to zero for unlimited.


#### emitter.listeners(event)

Returns an array of listeners for the specified event. This array can be
Expand Down
33 changes: 32 additions & 1 deletion lib/events.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
var EventEmitter = exports.EventEmitter = process.EventEmitter;

var isArray = Array.isArray;

// By default EventEmitters will print a warning if more than
// 10 listeners are added to it. This is a useful default which
// helps finding memory leaks.
//
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
var defaultMaxListeners = 10;
EventEmitter.prototype.setMaxListeners = function(n) {
this._events.maxListeners = n;
};


EventEmitter.prototype.emit = function(type) {
// If there is no 'error' event listener then throw.
if (type === 'error') {
Expand Down Expand Up @@ -71,6 +82,26 @@ EventEmitter.prototype.addListener = function(type, listener) {
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
} else if (isArray(this._events[type])) {

// Check for listener leak
if (!this._events[type].warned) {
var m;
if (this._events.maxListeners !== undefined) {
m = this._events.maxListeners;
} else {
m = defaultMaxListeners;
}

if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
console.trace();
}
}

// If we've already got an array, just append.
this._events[type].push(listener);
} else {
Expand Down

2 comments on commit bdb1464

@msiebuhr
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great!

It enabled quickly finding a memory leak in the riak-js driver: https://github.com/frank06/riak-js/issues/issue/31/

@ry
Copy link
Author

@ry ry commented on bdb1464 Jan 6, 2011

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, i'm glad to hear that!

Please sign in to comment.