(node) warning: possible EventEmitter memory leak detected.
Ошибка, которая будоражит умы многих разработчиков. Я тут поседел еще больше пока решал как её обойти.[spoiler]
Что такое утечка памяти интересно и подробно рассказано тут.
Я рассмотрю конкретный кейс.
Задача: есть некий хост - сервер. К нему я подключаюсь по net socket используя адрес и порт.
Время от времени порт закрывается и подключение пропадает. Нужно ждать когда порт откроется и подключиться снова.
var net = require('net');
const client = new net.Socket();
let _connect_ = function () {
client.connect(port, host, function (err) {
if (err) {
console.log("error");
console.log(err);
}
console.log("connected");
});
}
client.on('error', function () {
console.log("connection error");
setTimeout(function(){_connect_();}, 1000);
});
Тут то мы и получаем утечку памяти. Т.к. подобная схема плодит бесконечное количество подписок на события client.on 'error'. А если мы добавим еще обработчиков событий (client.on 'data', например), то их количество увеличиться кратно.
Добрые люди советуют указать такую строку в начале:
process.setMaxListeners(0);
Правильно решать такую проблему нужно удалением не нужных прослушивателей. Для этого есть команда:
client.removeAllListeners();
Итак финальный вариант примерно такой:
var net = require('net');
const client = new net.Socket();
let _connect_ = function () {
client.connect(port_one, host_one, function (err) {
if (err) {
console.log("error");
console.log(err);
}
console.log("connected");
});
}
client.on('error', function () {
console.log("connection error");
reconnect ();
});
function reconnect () {
client.removeAllListeners();
client.on('error', function () {
console.log("connection error");
});
setTimeout(function(){_connect_();}, 1000);
}