Querying a MySQL database from a NodeJS AWS Lambda Function - mysql

I'm having a problem querying my MySQL database (hosted remotely from AWS) inside of my AWS Lambda function.
This is my code except for the parts I need for the rest of Lambda function (which is being called for an Alexa Skill):
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '<myserver>',
user : '<myusername>',
password : '<mypw>',
database : '<mydatabase>'
});
connection.connect(function(err){
if(!err) {
console.log("Database is connected ... nn");
}
else {
console.log("Error connecting database ... nn");
}
});
connection.query("INSERT INTO Users (user_id) VALUES ('TESTNAME')");
connection.end();
This works just fine when I run it with node from my command prompt:
node index.js
I'm using the "mysql" module installed via npm in the directory with index.js and zip it and upload it to my Lambda function.
Again, this works on my development machine, but gives no indicator when testing my Lambda function as to why it doesn't effect my database at all.
My question extends into Alexa and Lambda as much as it does the proper usage of the mysql Node.JS module.
Here's my current code for my Lambda, and the problem here, of course, is still that my test value -> a username called "TESTNAME" doesn't get added to my MySQL database.
I put the query into the connect callback as the first comment suggests, and I'm putting my new code instead of updating my old code above just to keep a record of what how I think the code should transition to being in my Alexa's Lambda function:
Updated code:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '<myserver>',
user : '<myusername>',
password : '<mypw>',
database : '<mydatabase>'
});
exports.handler = (event, context) => {
try {
if (event.session.new) {
// New Session
console.log("NEW SESSION");
}
switch (event.request.type) {
case "LaunchRequest":
// Launch Request
console.log(`LAUNCH REQUEST`);
context.succeed(
generateResponse({},
buildSpeechletResponse("Welcome to an Alexa Skill, this is running on a deployed lamda function", true)
)
);
break;
case "IntentRequest":
// Intent Request
console.log(`Intent Request`);
console.log('Then run MySQL code:');
connection.connect(function(err) {
console.log('Inside connection.connect() callback');
if (!err) {
console.log("Database is connected ... ");
connection.query("INSERT INTO Users (user_id) VALUES ('TESTNAME')",
function(err, result) {
console.log("Inside connection.query() callback")
if (!err) {
console.log("Query Successful! Ending Connectection.");
connection.end();
} else {
console.log("Query error!");
}
});
} else {
console.log("Error connecting database ..." + err.message);
}
});
context.succeed(
generateResponse({},
buildSpeechletResponse("Welcome to the incredible intelligent MySQLable Alexa!", true)
)
);
break;
case "SessionEndedRequest":
// Session Ended Request
console.log(`SESSION ENDED REQUEST`);
break;
default:
context.fail(`INVALID REQUEST TYPE: ${event.request.type}`);
}
} catch (error) {
context.fail(`Exceptiodn: ${error}`)
}
};
//Helpers
buildSpeechletResponse = (outputText, shouldEndSession) => {
return {
outputSpeech: {
type: "PlainText",
text: outputText
},
shouldEndSession: shouldEndSession
};
};
generateResponse = (sessionAttributes, speechletResponse) => {
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
};
};
And my console output:
START RequestId: 5d4d17a7-0272-11e7-951c-b3d6944457e1 Version: $LATEST
2017-03-06T13:39:47.561Z 5d4d17a7-0272-11e7-951c-b3d6944457e1 Intent Request
2017-03-06T13:39:47.562Z 5d4d17a7-0272-11e7-951c-b3d6944457e1 Then run MySQL code:
END RequestId: 5d4d17a7-0272-11e7-951c-b3d6944457e1
REPORT RequestId: 5d4d17a7-0272-11e7-951c-b3d6944457e1 Duration: 82.48 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 14 MB

The problem was that I needed to put my context.succeed inside of my callbacks. Many thanks to sqlbot, as his talk of callbacks led me to study where things were actually ending their execution.
So apparently when using AWS Lambda, if the "context" ends before your callbacks get called, you don't get your callbacks. So even though I had placed all of my callbacks like so: connect -> query -> end, the first callback of the chain from connect never gets called because "context.succeed" was getting called right afterwards, which ended execution.
Here's my code as of now (getting a proper query happening now):
var mysql = require('mysql');
var connection = mysql.createConnection({
...
});
exports.handler = (event, context) => {
try {
if (event.session.new) {
// New Session
console.log("NEW SESSION");
}
switch (event.request.type) {
case "LaunchRequest":
// Launch Request
console.log(`LAUNCH REQUEST`);
context.succeed(
generateResponse({},
buildSpeechletResponse("Welcome to an Alexa Skill, this is running on a deployed lamda function", true)
)
);
break;
case "IntentRequest":
// Intent Request
console.log(`Intent Request`);
console.log('Then run MySQL code:');
connection.connect(function(err) {
console.log('Inside connection.connect() callback');
if (!err) {
console.log("Database is connected ... ");
connection.query("INSERT INTO Users (user_id) VALUES ('TESTNAME')",
function(err, result) {
console.log("Inside connection.query() callback")
if (!err) {
console.log("Query Successful! Ending Connection.");
connection.end();
} else {
console.log("Query error!");
}
});
} else {
console.log("Error connecting database ..." + err.message);
}
context.succeed(
generateResponse({},
buildSpeechletResponse("Welcome to the incredible intelligent MySQLable Alexa!", true)
)
);
});
break;
case "SessionEndedRequest":
// Session Ended Request
console.log(`SESSION ENDED REQUEST`);
break;
default:
context.fail(`INVALID REQUEST TYPE: ${event.request.type}`);
}
} catch (error) {
context.fail(`Exceptiodn: ${error}`)
}
};
//Helpers
buildSpeechletResponse = (outputText, shouldEndSession) => {
return {
outputSpeech: {
type: "PlainText",
text: outputText
},
shouldEndSession: shouldEndSession
};
};
generateResponse = (sessionAttributes, speechletResponse) => {
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
};
};

Related

Connecting to MySql database from AWS Lambda function using Node.js, no connect callback

I am trying to connect an external (not AWS) MySql server from an AWS Lambda function written in Node.js using nodejs14.x environment, but the connect() callback is not called.
I am been struggling with this problem since days, there are a lot of references to similar issues but I really tried all possible permutations of solutions I found.
I am deploying with SAM and testing both on local machine and on real AWS.
Here is the sample code of the lambda helper
const mysql = require('mysql');
exports.helloFromLambdaHandler = async () => {
const message = 'Hello from Lambda!';
console.info(`${message}`);
var sql = "SELECT 1+? AS sum";
var values = [1];
console.log("Doing createConnection");
const connection = mysql.createConnection({
/* my connection data */
});
console.log("Doing connect");
connection.connect( (err) => {
console.log("Inside connection callback");
console.log('connected as id ' + connection.threadId);
if(!err) {
console.log("DB connected, thread id is " + connection.threadId);
console.log("Doing query");
connection.query(sql, values, (err, result, values) => {
console.log("Inside query callback");
if(!err) {
console.log("Query ok!");
console.log(result);
connection.end();
} else {
console.log("Error executing query: " + err.message);
}
});
} else {
console.log("Error connecting db: "+ err.message);
}
});
console.log ("Returning...");
return message;
}
The log is
Hello from Lambda!
Doing createConnection
Doing connect
Returning...
The expected behaviour is that after "Returning..." I should see the log "Inside connection callback" then "Inside query callback" and then "Query ok!".
Instead the callback of connect() appears not invoked.
I know that I can call query() directly skipping connect() but also doing so I encounter same issue.
Any clue?
Thank you!
SOLUTION
As suggested by the accepted answer, returning a promise is the solution to let Node complete all the queue. Unfortunately it's not possible to complete the Lambda and leave it running in background in a safe manner, for what I understand.
I am investigating alternative solutions such as:
mysql2 library which supports promises natively
serverless-mysql npm package which handles shared db connections
Below the running demo code
const mysql = require('mysql');
exports.helloFromLambdaHandler = async (event, context) => {
const message = 'Hello from Lambda!';
console.info(`${message}`);
var sql = "SELECT 1+? AS sum";
var values = [1];
console.log("Doing createConnection");
const connection = mysql.createConnection({
/* my connection data */
});
console.log("Doing query");
const promise = new Promise( (resolve, reject) => {
connection.query(sql, values, (err, result, values) => {
console.log("Inside query callback");
if(!err) {
console.log("Query ok!");
console.log(result);
connection.end();
resolve(message);
} else {
console.log("Error executing query: " + err.message);
reject(err);
}
});
});
console.log ("Returning...");
return promise;
}
You are using async handler, thus your function probably completes before your connect() has a chance to execute.
To try to overcome the issue, you can use Promise as shown in AWS docs.

Node.js MySQL connection with timer and error handling

I have a basic node.js app running as a service on RaspPi.
There should be two important issues:
Check MySQL database every 3 secs and get Status
Never throw even if internet connection is lost or MySQL server stops etc.
This code runs well but app closes and throw an error if MySQL server stops. It needs to be run even if there is an any kind of error. (No need to log and get error type)
And also; is this every 3 secs connection algorithm correct for performance?
var mysql = require('mysql');
var con = mysql.createConnection({
host: "192.168.1.100",
user: "test",
password: "test",
database: "test"
});
var Gpio = require('onoff').Gpio;
var LED = new Gpio(4, 'out'); //use GPIO pin 4
var getStatus = setInterval(checkStatus, 3000);
function checkStatus() {
try
{
con.connect(function(err) {
//if (err) throw err;
con.query("SELECT device_status FROM Device_Status WHERE
device_id='device01'", function (err, result, fields) {
if (err)
{
//console.log(err);
}
else
{
//console.log(result[0].device_status);
if(result[0].device_status == "1")
{
LED.writeSync(1);
}
else
{
LED.writeSync(0);
}
}
});
});
}
catch(err){ //console.log(err);
}
}
Have you thought about pooling connections? Then you would connect on every query.
connect() {
return new Promise((resolve, reject) => {
pool = mysql.createPool({
connectionLimit: 10,
host : this.host,
user : this.user,
password : this.password,
database : this.database
});
resolve(pool);
});
}
Then you would search like this:
search(collection, searchStr) {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
resolve(err);
} else {
var sql = "SELECT * FROM " + collection
if (searchStr)
sql += " WHERE " + searchStr;
connection.query(sql, (err, result) => {
if (err) reject(err);
resolve(result);
connection.release();
});
}
});
});
}
Can you check this code from my repo https://github.com/MathewJohn1414/node-mysql-quickstart
. It is uses the MySQL connection pool and the connection errors are also handled.

How to make multiple mysql queries in Node with promises

G'day all,
I'm trying to convert some old php code over to Node, and part of the journey has been trying to figure out the best way to perform sql queries against my database (I'm using SQL so I can port the existing database over).
I've got them working, but have encountered the "Pyramid of Doom" problem, and it's subsequent scope issues (i.e. the returned values not baing available to subsequent "then"s).
An example of the sort of code I have here is: (dbPool.queryOPromise returns a query wrapped in a promise)
dbPool.queryOPromise(query)
.then(function(result){
console.log(result);
var query = {
sql:"INSERT INTO newusers (newuserid, ipaddress, email) VALUES (?,?,?)",
values: [newuserid, ipAddress, email]
};
dbPool.queryOPromise(query)
.then(function(value){
console.log(value);
if(value.code==200) {
res.status(200).json({code:200, status:"New User Created"});
} else {
res.status(400).json({code:value.code, status:"Error creating new user: ".value.status});
}
})
})
Does anyone have a view on the best way to attack this situation?
Thanks!
You're supposed to return the subsequent promises instead of calling .then on them
dbPool.queryOPromise(query)
.then(function(result) {
console.log(result);
var query = {
sql: "INSERT INTO newusers (newuserid, ipaddress, email) VALUES (?,?,?)",
values: [newuserid, ipAddress, email]
};
// RETURN the second promise,
return dbPool.queryOPromise(query);
})
.then(function(value) {
console.log(value);
if (value.code == 200) {
res.status(200).json({code: 200, status: "New User Created"});
} else {
res.status(400).json({code: value.code, status: "Error creating new user: ".value.status });
}
})
.catch(console.error); // and always catch the errors at the end.
It's a #1 rookie mistake in using promises. Checkout this wonderfully written article addressing issues exactly like this
For node -v > 8.x only,
Share my working example:
I use this Promisified MySQL middleware for Node.js
read this article Create a MySQL Database Middleware with Node.js 8 and Async/Await
here is my database.js
var mysql = require('mysql');
// node -v must > 8.x
var util = require('util');
// !!!!! for node version < 8.x only !!!!!
// npm install util.promisify
//require('util.promisify').shim();
// -v < 8.x has problem with async await so upgrade -v to v9.6.1 for this to work.
// connection pool https://github.com/mysqljs/mysql [1]
var pool = mysql.createPool({
connectionLimit : process.env.mysql_connection_pool_Limit, // default:10
host : process.env.mysql_host,
user : process.env.mysql_user,
password : process.env.mysql_password,
database : process.env.mysql_database
})
// Ping database to check for common exception errors.
pool.getConnection((err, connection) => {
if (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
console.error('Database connection was closed.')
}
if (err.code === 'ER_CON_COUNT_ERROR') {
console.error('Database has too many connections.')
}
if (err.code === 'ECONNREFUSED') {
console.error('Database connection was refused.')
}
}
if (connection) connection.release()
return
})
// Promisify for Node.js async/await.
pool.query = util.promisify(pool.query)
module.exports = pool
You must upgrade node -v > 8.x
you must use async function to be able to use await.
example:
var pool = require('./database')
// node -v must > 8.x, --> async / await
router.get('/:template', async function(req, res, next)
{
...
try {
var _sql_rest_url = 'SELECT * FROM arcgis_viewer.rest_url WHERE id='+ _url_id;
var rows = await pool.query(_sql_rest_url)
_url = rows[0].rest_url // first record, property name is 'rest_url'
if (_center_lat == null) {_center_lat = rows[0].center_lat }
if (_center_long == null) {_center_long= rows[0].center_long }
if (_center_zoom == null) {_center_zoom= rows[0].center_zoom }
_place = rows[0].place
} catch(err) {
throw new Error(err)
}

node js: check mysql connection before a query

I use node js with mysql and want to avoid that the app crash on connection errors.At the moment i use this :
function mysql_handleDisconnect() {
mysql_connection = mysql.createConnection(mysql_config_obj); // Recreate the connection, since
// the old one cannot be reused.
mysql_connection.connect(function(err) { // The server is either down
if(err) { // or restarting (takes a while sometimes).
console.log('error when connecting to db:', err);
mysql_handleDisconnect(); // We introduce a delay before attempting to reconnect,
} // to avoid a hot loop, and to allow our node script to
}); // process asynchronous requests in the meantime.
// If you're also serving http, display a 503 error.
mysql_connection.on('error', function(err) {
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') { // Connection to the MySQL server is usually
mysql_handleDisconnect(); // lost due to either server restart, or a
} else { // connnection idle timeout (the wait_timeout
throw err; // server variable configures this)
}
});
}
mysql_handleDisconnect(mysql_connection);
so this is blocking because it leads to a hot loop if the connection is closed.my problem is, if i add a setTimeout to reestablish connection just every 2 seconds i could get an fatal error when i do a query with "mysql_connection.query('SELECT ...')".in this case the app crashes.
So my question is,if there's a possibility to check the connection before i do a query?
Try using below code in every microservice before doing anything:
if(connection.state === 'disconnected'){
return respond(null, { status: 'fail', message: 'server down'});
}
State of connection to DB could fall in 2 states:
disconnected (when due to DB server down or wrong config use for DB connection is wrong)
authenticated (when DB connection is successfully created to DB server).
So either check state == 'disconnected' or state == 'authenticated'
I know this is an old question but I have found connection.ping( (err) => {...}) to be very useful for health-checks made from load balancers and whatnot.
Every time, while I'm pushing my code in production, the mysql connection is lost. It is a very common problem in production, or local.
My solution is that At every query established the db connection and remove connection after completing the db query.
My solution is to establish the db connection before every query, and then remove the connection after completing the db query.
Step1: Here is the code for dbConnection.js
//this code is for conenct to db
const mysql = require('mysql2');
require('dotenv').config();
module.exports.stablishedConnection = ()=>{
return new Promise((resolve,reject)=>{
const con = mysql.createConnection( {
host: process.env.DB_HOST||localhost,
user: process.env.DB_USER_NAME||myUserName ,
password: process.env.DB_PASSWORD||mypassword,
database: process.env.DB_NAME||mydb
});
con.connect((err) => {
if(err){
reject(err);
}
resolve(con);
});
})
}
module.exports.closeDbConnection =(con)=> {
con.destroy();
}
Step2: For Router.js I am import the db connection and handle the promise
const router = require('express').Router();
const {stablishedConnection,closeDbConnection} =require('../db/dbConnection');
router.get('/user/:sId/:userId',function(req,res){
stablishedConnection()
.then((db)=>{
console.log("Db connection stablished");
db.query(`select * from user WHERE sent_id=${req.params.sId} AND user_id=${req.params.userId}`, null, function (err,data) {
if (!data) {
res.status(200).json({sucess:false,err});
}else{
res.status(200).json({sucess:true,data});
closeDbConnection(db);
console.log("Db Connection close Successfully");
}
})
}).catch((error)=>{
console.log("Db not connected successfully",error);
});
});
router.get('/sen/:userId',function(req,res){
stablishedConnection()
.then((db)=>{
console.log("Db connection stablished");
db.query(`select * from sen WHERE user_id=${req.params.userId}`, null, function (err,data) {
if (!data) {
res.status(200).json({sucess:false,err});
}else{
res.status(200).json({sucess:true,data});
closeDbConnection(db);
console.log("Db Connection close Successfully");
}
})
}).catch((error)=>{
console.log("Db not connected successfully",error);
});
});
router.get('/language',(req,res)=>{
stablishedConnection()
.then((db)=>{
console.log("Db connection stablished");
db.query("select * from language", null, function (err,data) {
if (!data) {
res.status(200).json({sucess:false,err});
}else{
res.status(200).json({sucess:true,data});
closeDbConnection(db);
console.log("Db Connection close Successfully")
}
})
}).catch((error)=>{
console.log("Db not connected successfully",error);
});
})
module.exports = router;
This is perfectly run If you want to create and close connection at every query ..
I solved this problem like this:
let connection = mysql.createConnection(DB_CONFIG);
function runDBQuery() {
const disconnected = await new Promise(resolve => {
connection.ping(err => {
resolve(err);
});
});
if (disconnected) {
connection = mysql.createConnection(DB_CONFIG);
}
... use actual connection
}

node.js + mysql connection pooling

I'm trying to figure out how to structure my application to use MySQL most efficent way. I'm using node-mysql module. Other threads here suggested to use connection pooling so i set up a little module mysql.js
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'localhost',
user : 'root',
password : 'root',
database : 'guess'
});
exports.pool = pool;
Now whenever I want to query mysql I require this module and then query the databse
var mysql = require('../db/mysql').pool;
var test = function(req, res) {
mysql.getConnection(function(err, conn){
conn.query("select * from users", function(err, rows) {
res.json(rows);
})
})
}
Is this good approach? I couldn't really find too much examples of using mysql connections besides very simple one where everything is done in main app.js script so I don't really know what the convention / best practices are.
Should I always use connection.end() after each query? What if I forget about it somewhere?
How to rewrite the exports part of my mysql module to return just a connection so I don't have to write getConnection() every time?
It's a good approach.
If you just want to get a connection add the following code to your module where the pool is in:
var getConnection = function(callback) {
pool.getConnection(function(err, connection) {
callback(err, connection);
});
};
module.exports = getConnection;
You still have to write getConnection every time. But you could save the connection in the module the first time you get it.
Don't forget to end the connection when you are done using it:
connection.release();
You should avoid using pool.getConnection() if you can. If you call pool.getConnection(), you must call connection.release() when you are done using the connection. Otherwise, your application will get stuck waiting forever for connections to be returned to the pool once you hit the connection limit.
For simple queries, you can use pool.query(). This shorthand will automatically call connection.release() for you—even in error conditions.
function doSomething(cb) {
pool.query('SELECT 2*2 "value"', (ex, rows) => {
if (ex) {
cb(ex);
} else {
cb(null, rows[0].value);
}
});
}
However, in some cases you must use pool.getConnection(). These cases include:
Making multiple queries within a transaction.
Sharing data objects such as temporary tables between subsequent queries.
If you must use pool.getConnection(), ensure you call connection.release() using a pattern similar to below:
function doSomething(cb) {
pool.getConnection((ex, connection) => {
if (ex) {
cb(ex);
} else {
// Ensure that any call to cb releases the connection
// by wrapping it.
cb = (cb => {
return function () {
connection.release();
cb.apply(this, arguments);
};
})(cb);
connection.beginTransaction(ex => {
if (ex) {
cb(ex);
} else {
connection.query('INSERT INTO table1 ("value") VALUES (\'my value\');', ex => {
if (ex) {
cb(ex);
} else {
connection.query('INSERT INTO table2 ("value") VALUES (\'my other value\')', ex => {
if (ex) {
cb(ex);
} else {
connection.commit(ex => {
cb(ex);
});
}
});
}
});
}
});
}
});
}
I personally prefer to use Promises and the useAsync() pattern. This pattern combined with async/await makes it a lot harder to accidentally forget to release() the connection because it turns your lexical scoping into an automatic call to .release():
async function usePooledConnectionAsync(actionAsync) {
const connection = await new Promise((resolve, reject) => {
pool.getConnection((ex, connection) => {
if (ex) {
reject(ex);
} else {
resolve(connection);
}
});
});
try {
return await actionAsync(connection);
} finally {
connection.release();
}
}
async function doSomethingElse() {
// Usage example:
const result = await usePooledConnectionAsync(async connection => {
const rows = await new Promise((resolve, reject) => {
connection.query('SELECT 2*4 "value"', (ex, rows) => {
if (ex) {
reject(ex);
} else {
resolve(rows);
}
});
});
return rows[0].value;
});
console.log(`result=${result}`);
}
You will find this wrapper usefull :)
var pool = mysql.createPool(config.db);
exports.connection = {
query: function () {
var queryArgs = Array.prototype.slice.call(arguments),
events = [],
eventNameIndex = {};
pool.getConnection(function (err, conn) {
if (err) {
if (eventNameIndex.error) {
eventNameIndex.error();
}
}
if (conn) {
var q = conn.query.apply(conn, queryArgs);
q.on('end', function () {
conn.release();
});
events.forEach(function (args) {
q.on.apply(q, args);
});
}
});
return {
on: function (eventName, callback) {
events.push(Array.prototype.slice.call(arguments));
eventNameIndex[eventName] = callback;
return this;
}
};
}
};
Require it, use it like this:
db.connection.query("SELECT * FROM `table` WHERE `id` = ? ", row_id)
.on('result', function (row) {
setData(row);
})
.on('error', function (err) {
callback({error: true, err: err});
});
I am using this base class connection with mysql:
"base.js"
var mysql = require("mysql");
var pool = mysql.createPool({
connectionLimit : 10,
host: Config.appSettings().database.host,
user: Config.appSettings().database.username,
password: Config.appSettings().database.password,
database: Config.appSettings().database.database
});
var DB = (function () {
function _query(query, params, callback) {
pool.getConnection(function (err, connection) {
if (err) {
connection.release();
callback(null, err);
throw err;
}
connection.query(query, params, function (err, rows) {
connection.release();
if (!err) {
callback(rows);
}
else {
callback(null, err);
}
});
connection.on('error', function (err) {
connection.release();
callback(null, err);
throw err;
});
});
};
return {
query: _query
};
})();
module.exports = DB;
Just use it like that:
var DB = require('../dal/base.js');
DB.query("select * from tasks", null, function (data, error) {
callback(data, error);
});
When you are done with a connection, just call connection.release() and the connection will return to the pool, ready to be used again by someone else.
var mysql = require('mysql');
var pool = mysql.createPool(...);
pool.getConnection(function(err, connection) {
// Use the connection
connection.query('SELECT something FROM sometable', function (error, results, fields) {
// And done with the connection.
connection.release();
// Handle error after the release.
if (error) throw error;
// Don't use the connection here, it has been returned to the pool.
});
});
If you would like to close the connection and remove it from the pool, use connection.destroy() instead. The pool will create a new connection the next time one is needed.
Source: https://github.com/mysqljs/mysql
You can use this format as I used
const mysql = require('mysql');
const { HOST, USERNAME, PASSWORD, DBNAME, PORT } = process.env;
console.log();
const conn = mysql.createPool({
host: HOST,
user: USERNAME,
password: PASSWORD,
database: DBNAME
}, { debug: true });
conn.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) throw error;
console.log('Db is connected - The solution is: ', results[0].solution);
});
module.exports = conn;
Using the standard mysql.createPool(), connections are lazily created by the pool. If you configure the pool to allow up to 100 connections, but only ever use 5 simultaneously, only 5 connections will be made. However if you configure it for 500 connections and use all 500 they will remain open for the durations of the process, even if they are idle!
This means if your MySQL Server max_connections is 510 your system will only have 10 mySQL connections available until your MySQL Server closes them (depends on what you have set your wait_timeout to) or your application closes! The only way to free them up is to manually close the connections via the pool instance or close the pool.
mysql-connection-pool-manager module was created to fix this issue and automatically scale the number of connections dependant on the load. Inactive connections are closed and idle connection pools are eventually closed if there has not been any activity.
// Load modules
const PoolManager = require('mysql-connection-pool-manager');
// Options
const options = {
...example settings
}
// Initialising the instance
const mySQL = PoolManager(options);
// Accessing mySQL directly
var connection = mySQL.raw.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
// Initialising connection
connection.connect();
// Performing query
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
// Ending connection
connection.end();
Ref: https://www.npmjs.com/package/mysql-connection-pool-manager
i always use connection.relase(); after pool.getconnetion like
pool.getConnection(function (err, connection) {
connection.release();
if (!err)
{
console.log('*** Mysql Connection established with ', config.database, ' and connected as id ' + connection.threadId);
//CHECKING USERNAME EXISTENCE
email = receivedValues.email
connection.query('SELECT * FROM users WHERE email = ?', [email],
function (err, rows) {
if (!err)
{
if (rows.length == 1)
{
if (bcrypt.compareSync(req.body.password, rows[0].password))
{
var alldata = rows;
var userid = rows[0].id;
var tokendata = (receivedValues, userid);
var token = jwt.sign(receivedValues, config.secret, {
expiresIn: 1440 * 60 * 30 // expires in 1440 minutes
});
console.log("*** Authorised User");
res.json({
"code": 200,
"status": "Success",
"token": token,
"userData": alldata,
"message": "Authorised User!"
});
logger.info('url=', URL.url, 'Responce=', 'User Signin, username', req.body.email, 'User Id=', rows[0].id);
return;
}
else
{
console.log("*** Redirecting: Unauthorised User");
res.json({"code": 200, "status": "Fail", "message": "Unauthorised User!"});
logger.error('*** Redirecting: Unauthorised User');
return;
}
}
else
{
console.error("*** Redirecting: No User found with provided name");
res.json({
"code": 200,
"status": "Error",
"message": "No User found with provided name"
});
logger.error('url=', URL.url, 'No User found with provided name');
return;
}
}
else
{
console.log("*** Redirecting: Error for selecting user");
res.json({"code": 200, "status": "Error", "message": "Error for selecting user"});
logger.error('url=', URL.url, 'Error for selecting user', req.body.email);
return;
}
});
connection.on('error', function (err) {
console.log('*** Redirecting: Error Creating User...');
res.json({"code": 200, "status": "Error", "message": "Error Checking Username Duplicate"});
return;
});
}
else
{
Errors.Connection_Error(res);
}
});