Mysql: (node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.

Created on 21 Jan 2015  路  9Comments  路  Source: mysqljs/mysql

Hi,

I am using Pool node-mysql 2.5.4 with express.js to query a database with connectionLimit=10.

and when I get around 12-16 connections (checking using ''netstat -an | grep 127.0.0.1._3306._ESTABLISHED | wc -l") when many clients are connected, I get this message: "(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.". I have set req.setMaxListeners(0); ( http://nodejs.org/docs/latest/api/events.html#events_emitter_setmaxlisteners_n) in express request method, but still no effect.

I have three questions:

  1. with connectionLimit=10, what is truly means? Does it limit the no. of current sessions to 10 max? That doesn't seem to be the case, because I see 12-16 connections on port 3306 (sometimes 18)
  2. also, what is the recommended connectionLimit?
  3. Is there a way to avoid that warning message?

Thanks

question

Most helpful comment

Thanks! So the bug is in your code there. Every call made to runQry has the same pool (this is fine), but you add a listener on it every time. You only need to make 11 calls and you get that warning. You just need to stop adding the same listener over and over again.

In fact, it seems like all you're trying to do is make it an error for getConnect to queue; there is an option that will do this for you.

All 9 comments

Can you point to what line in the source of this module is generating that message?

Here is the trace... i think its the line: /apps/clink-prod/clink/ndt/node_modules/mysql/lib/protocol/Protocol.js:271:23

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
at Pool.addListener (events.js:160:15)
at MySqlClient.runQry (/apps/clink-prod/clink/ndt/modules/mysql_client.js:63:15)
at MySqlClient.getBundleNameByAssocIntfId as getIntfBundleAssoc
at /apps/clink-prod/clink/ndt/nwmap/app.js:229:19
at runQryCb (/apps/clink-prod/clink/ndt/modules/mysql_client.js:104:20)
at Query._callback (/apps/clink-prod/clink/ndt/modules/mysql_client.js:79:20)
at Query.Sequence.end (/apps/clink-prod/clink/ndt/node_modules/mysql/lib/protocol/sequences/Sequence.js:96:24)
at Query._handleFinalResultPacket (/apps/clink-prod/clink/ndt/node_modules/mysql/lib/protocol/sequences/Query.js:143:8)
at Query.EofPacket (/apps/clink-prod/clink/ndt/node_modules/mysql/lib/protocol/sequences/Query.js:127:8)
at Protocol._parsePacket (/apps/clink-prod/clink/ndt/node_modules/mysql/lib/protocol/Protocol.js:271:23)

Your trace shows it's caused by whatever code you have at /apps/clink-prod/clink/ndt/modules/mysql_client.js:63:15

well, thats just the beginning trace... i don't have anything related to eventemitter in my code. i am just calling mysql lib in express.js, but not closing the pool ever. may be due to that?

Van you paste that file of yours I referenced?

In think its this line...

    this.pool.on('enqueue', function () {

I have removed some company specific stuff from the code, but here is the generic code...

/**
 * mysql_client
 */

// Import modules
var mysql = require('mysql');
var path = require('path');
var fs = require('fs');
var async = require('async');

// Export module with Namespace
var mysqlc = exports;

// Constants
var DEFAULT_MYSQL_PORT = 3306;
var DEFAULT_AUTOCOMMIT = false;
var DEFAULT_CONNLIMIT = 10;

/**
 * MySQL Class Wrapper
 * @param {string} user: user of database account
 * @param {string} password: password for database account
 * @param {string} database: database name
 * @param {string} host: hostname of server
 * @param {string} port: port of server
 * @param {boolean} autocommit: autocommit
 * @return {object} object
 */
mysqlc.MySqlClient = function MySqlClient(connProp) {
    "use strict";
    this.user = connProp.user;
    this.password = connProp.password;
    this.database = connProp.database;
    this.host = connProp.host;
    this.port = connProp.port || DEFAULT_MYSQL_PORT;
    this.autocommit = connProp.autocommit || DEFAULT_AUTOCOMMIT;
    this.connectionLimit = connProp.connectionLimit || DEFAULT_CONNLIMIT
    this.pool = null;

    this.connProp = {
            connectionLimit : this.connectionLimit,
            host            : this.host,
            port            : this.port,
            user            : this.user,
            password        : this.password,
            database        : this.database
    };
}


mysqlc.MySqlClient.prototype.runQry = function runQry(qry, args, callback) {
    this.pool.on('enqueue', function () {
        console.error('runQry-Waiting for available connection slot-ERROR');
        return callback('pool-not-empty');
    });
    console.log('running mysql qry:', qry);
    this.pool.getConnection(function(err, connection) {
        if (err) {
            console.error('runQry-cannot getConnection ERROR:', err);
            return callback(err);
        }
        connection.query(qry, args, function(err, rows) {
            if (err) {
                console.error('runQry-cannot run qry ERROR:', err);
                return callback(err);
            }
            connection.release();
            return callback(null, rows);
        });
    });
};

mysqlc.MySqlClient.prototype.connect = function connect(callback) {
    var pool = mysql.createPool(this.connProp);
    this.pool = pool;

    // verify connection
    pool.getConnection(function(err, connection) {
        console.log('connecting mysql');
        if (err) {
            console.error('ERROR connecting to mysql server with connProp:', this.connProp);
            return callback(err);
        }
        connection.release();
        return callback(null);
    });
};

mysqlc.MySqlClient.prototype.disconnect = function disconnect(callback) {
    var pool = this.pool;
    pool.getConnection(function(err, connection) {
        console.log('disconnecting mysql');
        if (err) {
            console.error('ERROR disconnecting to mysql server with connProp:', this.connProp);
            return callback(err);
        }
        connection.release();
        pool.end();
        return callback(null);
    });
}

Thanks! So the bug is in your code there. Every call made to runQry has the same pool (this is fine), but you add a listener on it every time. You only need to make 11 calls and you get that warning. You just need to stop adding the same listener over and over again.

In fact, it seems like all you're trying to do is make it an error for getConnect to queue; there is an option that will do this for you.

oh.. that makes sense.. in that case, i should simply add the enqueue listener in connect function as i call connect() only once. thanks a lot :+1:

No problem!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

acefxlabs picture acefxlabs  路  4Comments

winzig picture winzig  路  4Comments

macias picture macias  路  3Comments

johnrc picture johnrc  路  3Comments

ajpyoung picture ajpyoung  路  4Comments