node-mysql2 icon indicating copy to clipboard operation
node-mysql2 copied to clipboard

Can't add new command when connection is in closed state

Open rkgupta12 opened this issue 1 year ago • 0 comments

The error is coming very frequently even if all config is correctly set and ping method is in place.

configuration used as below

 const dbPool = mySql.createPool(Object.assign({}, defaultDBConfig, {
            database: service.db,
            waitForConnections: true,
            connectionLimit: 25,
            queueLimit: 0,
            multipleStatements: true,
            dateStrings: true,
            idleTimeout: 60000,
            enableKeepAlive: true
        }));

This error is coming every one or other day mostly in night when application is not used.. however I used a ping method to keep connection alive test in each 30 min

 setInterval(async () => {
            try {
                await keepConnectionsAlive(dbConnection.dbPool);
            } catch (err) {
                console.log(`Error during keep-alive process: ${err} at ${new Date()}`);
            }
        }, 1800000); // 30 min interval
        
        // Function to keep connections alive
async function keepConnectionsAlive(pool) {
    const promises = [];
    const connectionLimit = pool.pool.config.connectionLimit;
    const timeout = 500; // Timeout in milliseconds to attempt getting a connection

    for (let i = 0; i < connectionLimit; i++) {
        promises.push(
            (async () => {
                let connection;
                try {
                    connection = await Promise.race([
                        pool.getConnection(),
                        new Promise((_, reject) =>
                            setTimeout(() => reject(new Error('Timeout getting connection')), timeout)
                        )
                    ]);
                    // Validate the connection
                    const isValid = await pool.validate(connection);
                    if (!isValid) {
                        console.log(`Invalid connection ${connection.threadId} detected and destroyed at: ${new Date()}`);
                       await connection.destroy(); // Destroy the invalid connection
                    } else {
                        console.log(`Database connection ${connection.threadId} is alive at: ${new Date()}`);
                    }
                } catch (err) {
                    if (err.message === 'Timeout getting connection') {
                        console.log(`Skipping connection health check due to timeout at ${new Date()}`);
                    } else {
                        console.log(`Error when checking database health: ${err} at ${new Date()}`);
                        if (connection) {
                            await connection.destroy();
                        }
                    }
                } finally {
                    if (connection) {
                        try {
                        await connection.release();
                        } catch (err) {
                            console.log(`Error when releasing connection during healthceck health: ${err} at ${new Date()}`);
                        }
                    }
                }
            })()
        );
    }

    await Promise.all(promises).catch(err => {
        console.log(`Error during Promise.all: ${err}`);
    });
}

rkgupta12 avatar Aug 17 '24 15:08 rkgupta12