Reputation: 3857
right now I have the listeners code like the following. However, my server keeps telling me
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
at EventEmitter.addListener (events.js:160:15)
at Hub.<anonymous> (/home/ec2-user/AjaxIM-retail/server/middleware/im/hub.js:88:33)
at /home/ec2-user/AjaxIM-retail/server/libs/utils.js:43:23
at IncomingMessage.<anonymous> (/home/ec2-user/AjaxIM-retail/server/libs/authentication/lp/index.js:75:33)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:920:16
at process._tickCallback (node.js:415:13)
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
I read some posts and some people advise me to "not add too many listeners"... Is that correct? What should I do?
this.events.addListener('update', o_.bind(function(package) {
if(this.clear != 0){
delete this.sessions[this.clear];
}
var _package = package.toJSON();
if(package.type == 'status' && package.status == 'offline') {
var sids = Object.keys(this.sessions), sid, sess;
for(sid in this.sessions) {
sess = this.sessions[sid];
if(sess.data('username') == package.username) {
if(sess.listeners.length)
sess.send(200, {type: 'goodbye'});
delete this.sessions[sid];
break;
}
}
}
}, this));
};
Hub.prototype.destroy = function(sid, fn) {
this.set(sid, null, fn);
};
Hub.prototype.reap = function(ms) {
var threshold = +new Date - ms,
sids = Object.keys(this.sessions);
for(var i = 0, len = sids.length; i < len; ++i) {
var sid = sids[i], sess = this.sessions[sid];
if(sess.lastAccess < threshold) {
this.events.emit('update', new packages.Offline(sess.data('username')));
}
}
};
Hub.prototype.get = function(req, fn) {
if(this.sessions[req.sessionID]) {
fn(null, this.sessions[req.sessionID]);
} else {
this.auth.authenticate(req, o_.bind(function(data) {
if(data) {
var session = new User(req.sessionID, data);
this.set(req.sessionID, session);
this.auth.friends(req, data, o_.bind(function(friends) {
var friends_copy = friends.slice();
o_.values(this.sessions).filter(function(friend) {
return ~friends.indexOf(friend.data('username'));
}).forEach(function(friend) {
var username = friend.data('username');
friends_copy[friends_copy.indexOf(username)] =
[username, friend.status()];
}, this);
session._friends(friends_copy);
session.events.addListener('status',
o_.bind(function(value, message) {
this.events.emit(
'update',
new packages.Status(session.data('username'),
value,
message)
);
}, this));
this.events.addListener('update',
o_.bind(session.receivedUpdate, session));
this.set(req.sessionID, session);
fn(null, session);
}, this));
} else {
fn();
}
}, this));
}
};
I honestly think it is fine. Is there any problems? Please advise. Because my node.js server crushes every 10-20 hours now and keeps throwing me this listener warning and socket hang up error like this:
events.js:72
throw er; // Unhandled 'error' event
^
Error: socket hang up
at SecurePair.error (tls.js:999:23)
at EncryptedStream.CryptoStream._done (tls.js:695:22)
at CleartextStream.read [as _read] (tls.js:496:24)
at CleartextStream.Readable.read (_stream_readable.js:320:10)
at EncryptedStream.onCryptoStreamFinish (tls.js:301:47)
at EncryptedStream.g (events.js:175:14)
at EncryptedStream.EventEmitter.emit (events.js:117:20)
at finishMaybe (_stream_writable.js:354:12)
at endWritable (_stream_writable.js:361:3)
at EncryptedStream.Writable.end (_stream_writable.js:339:5)
at EncryptedStream.CryptoStream.end (tls.js:633:31)
Upvotes: 5
Views: 3226
Reputation: 13570
Here's the code from node.js standart library, which triggers this warning: https://github.com/joyent/node/blob/master/lib/events.js#L160-L176. So it basically just checking if your EventEmitter has more than 10 (by default) listeners attached. You can change this value by calling setMaxListeners (passing 0 means no limit).
So the warning itself has nothing to do with the crash. But it really can be caused by a leak, that is when you make a temporary object, then attach a listener function, which captures the object in a closure and then do not remove listener, which causes an object to stay in memory forever. Maybe this is your case. If not, just set the limit to an appropriate value, if it is — well, it means that the whole max listeners things really helps to find leaks.
Upvotes: 5