Queries in loop - Connection lost - Node JS - mysql

I'm trying to execute a bunch of really big SELECT statements (each of them require several minutes to complete execution) in a while loop.
var con = mysql.createConnection(
{
host: "host_name",
user: "user_name",
password: "password",
database: "database_name"
});
con.connect();
while(arg1 < arg2)
{
var query = SELECT * FROM table WHERE value=arg1;
con.query(query, function (err, result)
{
//Rest of code
});
arg = arg + 1;
}
con.end();
At first, it's working but soon, after a certain amount of time, the connection seems to be lost.
Connection lost: The server closed the connection.
at Protocol.end (C:\Users\X\node_modules\mysql\lib\protocol\Protocol.js:109:13)
at Socket.<anonymous> (C:\Users\X\node_modules\mysql\lib\Connection.js:109:28)
at emitNone (events.js:110:20)
at Socket.emit (events.js:207:7)
at endReadableNT (_stream_readable.js:1047:12)
at _combinedTickCallback (internal/process/next_tick.js:102:11)
at process._tickCallback (internal/process/next_tick.js:161:9)
After reading a few similar issues on Stack, I understood the cause thanks to the page of Mysql on Github :
You may lose the connection to a MySQL server due to network problems, the server timing you out, the server being restarted, or crashing.
So to handle the possible disconnection, I tried to use this function, following the work of a previous post :
function handleDisconnect() {
connection = mysql.createConnection(db_config);
connection.connect(function(err) {
if(err) {
console.log('error when connecting to db:', err);
setTimeout(handleDisconnect, 2000);
}
});
connection.on('error', function(err) {
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') {
handleDisconnect();
}
else
{
throw err;
}
});
}
In the following code :
while(arg1 < arg2)
{
handleDisconnect();
var query = SELECT * FROM table WHERE value=arg1;
connection.query(query, function (err, result)
{
//Rest of code
});
arg = arg + 1;
}
But I still get the following error message :
error when connecting to db: { Error: Connection lost: The server closed the connection.
at Protocol.end (C:\Users\X\node_modules\mysql\lib\protocol\Protocol.js:109:13)
at Socket.<anonymous> (C:\Users\X\node_modules\mysql\lib\Connection.js:109:28)
at emitNone (events.js:110:20)
at Socket.emit (events.js:207:7)
at endReadableNT (_stream_readable.js:1047:12)
at _combinedTickCallback (internal/process/next_tick.js:102:11)
at process._tickCallback (internal/process/next_tick.js:161:9)
--------------------
at Protocol._enqueue (C:\Users\X\node_modules\mysql\lib\protocol\Protocol.js:141:48)
at Protocol.handshake (C:\Users\X\node_modules\mysql\lib\protocol\Protocol.js:52:41)
at Connection.connect (C:\Users\X\node_modules\mysql\lib\Connection.js:130:18)
at handleDisconnect (C:\Users\X\connection.js:182:13)
at Object.<anonymous> (C:\Users\X\connection.js:105:2)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3) fatal: true, code: 'PROTOCOL_CONNECTION_LOST' }
C:\Users\X\connection.js:213
if (err) throw err;
^
Error: Connection lost: The server closed the connection.
at Protocol.end (C:\Users\X\node_modules\mysql\lib\protocol\Protocol.js:109:13)
at Socket.<anonymous> (C:\Users\X\node_modules\mysql\lib\Connection.js:109:28)
at emitNone (events.js:110:20)
at Socket.emit (events.js:207:7)
at endReadableNT (_stream_readable.js:1047:12)
at _combinedTickCallback (internal/process/next_tick.js:102:11)
at process._tickCallback (internal/process/next_tick.js:161:9)
--------------------
at Protocol._enqueue (C:\Users\X\node_modules\mysql\lib\protocol\Protocol.js:141:48)
at Protocol.handshake (C:\Users\X\node_modules\mysql\lib\protocol\Protocol.js:52:41)
at Connection.connect (C:\Users\X\node_modules\mysql\lib\Connection.js:130:18)
at handleDisconnect (C:\Users\X\connection.js:182:13)
at Object.<anonymous> (C:\Users\X\connection.js:105:2)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
Is there something I don't get or is there something that I should be aware of to succefully manage the disconnection ? I still have troubles in Node JS understanding how to handle the notions of synchronous and asynchronous functions, maybe my problem comes from here.

Related

Calling a function in a callback function in NodeJs

I am trying to implement this solution to my code. However, I am having trouble trying to call a function in a callback function.
In my index.js file, I have this
const db = require('./models/db.js');
db.connectDb();
In my db.js file, I have the following:
const mysql = require('mysql');
const database = {
//Connects to the DB
connectDb : function () {
// Create connection
this.db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'example'
});
this.db.connect(function(err){
if(err){
console.log("An error has occured when trying to connect to db.");
throw err;
}
console.log("MySQL Connected...");
});
this.db.on('error', function (err) {
var currentdate = new Date();
consoleoccurredn error has occured # ', currentdate,' with error:', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') {
this.handleDisconnect();
} else {
throw err;
}
});
},
handleDisconnect: function () {
this.connectDb();
}
}
module.exports = database;
The server starts up and MySQL connection has been successfully created. Since my intention is to handle the error connection lost, I restarted the server, and as expected, this.db.on('error', function (err) is executed, as reflected in the terminal.
MySQL Connected...
An error has occurred # [datetime] with error: Error: Connection lost: The server closed the connection.
at Protocol.end (/home/folder/node_modules/mysql/lib/protocol/Protocol.js:112:13)
at Socket.<anonymous> (/home/folder/node_modules/mysql/lib/Connection.js:94:28)
at Socket.<anonymous> (/home/folder/node_modules/mysql/lib/Connection.js:526:10)
at Socket.emit (node:events:538:35)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
fatal: true,
code: 'PROTOCOL_CONNECTION_LOST'
}
However, I get this error:
/home/folder/models/db.js:27
this.handleDisconnect();
^
TypeError: this.handleDisconnect is not a function
at Connection.<anonymous> (/home/folder/models/db.js:27:22)
at Connection.emit (node:events:526:28)
at Connection._handleProtocolError (/home/folder/node_modules/mysql/lib/Connection.js:423:8)
at Protocol.emit (node:events:526:28)
at Protocol._delegateError (/home/folder/node_modules/mysql/lib/protocol/Protocol.js:398:10)
at Protocol.end (/home/folder/node_modules/mysql/lib/protocol/Protocol.js:116:8)
at Socket.<anonymous> (/home/folder/node_modules/mysql/lib/Connection.js:94:28)
at Socket.<anonymous> (/home/folder/node_modules/mysql/lib/Connection.js:526:10)
at Socket.emit (node:events:538:35)
at endReadableNT (node:internal/streams/readable:1345:12)
[nodemon] app crashed - waiting for file changes before starting...
My question: Does this error have to do with trying to call a function outside of a callback function? Is it possible to call a function outside of a callback function, and that callback function is inside an object's function? Or is the problem something else?
For your reference, here is what is outputted in the terminal.
MySQL Connected...
An error has occurred # [datetime] with error: Error: Connection lost: The server closed the connection.
at Protocol.end (/home/folder/node_modules/mysql/lib/protocol/Protocol.js:112:13)
at Socket.<anonymous> (/home/folder/node_modules/mysql/lib/Connection.js:94:28)
at Socket.<anonymous> (/home/folder/node_modules/mysql/lib/Connection.js:526:10)
at Socket.emit (node:events:538:35)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
fatal: true,
code: 'PROTOCOL_CONNECTION_LOST'
}
/home/folder/models/db.js:27
this.handleDisconnect();
^
TypeError: this.handleDisconnect is not a function
at Connection.<anonymous> (/home/folder/models/db.js:27:22)
at Connection.emit (node:events:526:28)
at Connection._handleProtocolError (/home/folder/node_modules/mysql/lib/Connection.js:423:8)
at Protocol.emit (node:events:526:28)
at Protocol._delegateError (/home/folder/node_modules/mysql/lib/protocol/Protocol.js:398:10)
at Protocol.end (/home/folder/node_modules/mysql/lib/protocol/Protocol.js:116:8)
at Socket.<anonymous> (/home/folder/node_modules/mysql/lib/Connection.js:94:28)
at Socket.<anonymous> (/home/folder/node_modules/mysql/lib/Connection.js:526:10)
at Socket.emit (node:events:538:35)
at endReadableNT (node:internal/streams/readable:1345:12)
[nodemon] app crashed - waiting for file changes before starting...
The problem calling this.handleDisconnect() in this code:
this.db.on('error', function (err) {
var currentdate = new Date();
if(err.code === 'PROTOCOL_CONNECTION_LOST') {
this.handleDisconnect();
} else {
throw err;
}
});
is that the value of this is not what you need it to be and that's why you get the error that this.handleDisconnect is not a function (it's probably undefined). A plain function callback will set its own value of this according to how the caller (which is your database) calls it. Instead, you can change it to an arrow function and it will retain the desired value of this. This is the main reason that arrow functions were invented (to preserve the lexical value of this):
this.db.on('error', (err) => {
var currentdate = new Date();
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
this.handleDisconnect();
} else {
throw err;
}
});
Another problem here is that throw err in this context will not be useful. You will throwing back into some asynchronous context in your database and that's not anywhere that you can catch or handle that error or do anything useful with it. So, you will need a more useful way to process that error.

The mysql server disconnects every night, how do I resolve it?

I leave my computer on 24 hours, but I still lose connection with the MySQL server. My WiFi runs smoothly and is never disconnected because I'm still able to use the internet along with my other electronics. The error message says
The server closed the connection.
Is this inferring a problem on my computer/connection or with MySQL? Or is it my codes? Please advise.
Error messages:
events.js:174
throw er; // Unhandled 'error' event
^
Error: Connection lost: The server closed the connection.
at Protocol.end (C:\Users\Nick\Desktop\MyBot\node_modules\mysql\lib\protocol\Protocol.js:112:13)
at Socket.<anonymous> (C:\Users\Nick\Desktop\MyBot\node_modules\mysql\lib\Connection.js:97:28)
at Socket.<anonymous> (C:\Users\Nick\Desktop\MyBot\node_modules\mysql\lib\Connection.js:525:10)
at Socket.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1145:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
at Connection._handleProtocolError (C:\Users\Nick\Desktop\MyBot\node_modules\mysql\lib\Connection.js:426:8)
at Protocol.emit (events.js:198:13)
at Protocol._delegateError (C:\Users\Nick\Desktop\MyBot\node_modules\mysql\lib\protocol\Protocol.js:398:10)
at Protocol.end (C:\Users\Nick\Desktop\MyBot\node_modules\mysql\lib\protocol\Protocol.js:116:8)
at Socket.<anonymous> (C:\Users\Nick\Desktop\MyBot\node_modules\mysql\lib\Connection.js:97:28)
[... lines matching original stack trace ...]
at process._tickCallback (internal/process/next_tick.js:63:19)
My codes:
let con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
database: 'db',
dateStrings: 'date',
});
const handleDisconnect = () => {
con.connect(err => {
if (err) throw err;
console.log("Connected!");
});
con.on('err', err => {
console.log('db error', err);
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
handleDisconnect();
} else {
throw err;
}
});
}
handleDisconnect();

Unable to connect to google cloud sql service using node.js

I am trying to connect to my google-cloud-sql instance using my node.js mysql module and I am unable to connect to it. I referred to the following links mysql docs and google getting started but could not understand what's going on.
var connection = mysql.createConnection({
acquireTimeout: 30000,
host : '35.184.77.86',
user : 'XXX',
password : 'XXX',
database : 'name',
});
connection.connect(function(err){
if (err) {
console.error(chalk.red('error connecting: ' + err.stack));
return;
}
console.log(chalk.green('connected as id ' + connection.threadId));
});
connection.query('SELECT * FROM likes', function(err, rows, fields)
{
if (err) {
console.log(chalk.red(err));
}else{
console.log(fields);
}
});
connection.end();
I am getting the following error while connecting.
error connecting: Error: connect ETIMEDOUT
at Connection._handleConnectTimeout (/Users/narenpalep/Desktop/javascript/Project_Portfolio/node_modules/mysql/lib/Connection.js:419:13)
at Socket.g (events.js:292:16)
at emitNone (events.js:86:13)
at Socket.emit (events.js:185:7)
at Socket._onTimeout (net.js:338:8)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)
--------------------
at Protocol._enqueue (/Users/narenpalep/Desktop/javascript/Project_Portfolio/node_modules/mysql/lib/protocol/Protocol.js:145:48)
at Protocol.handshake (/Users/narenpalep/Desktop/javascript/Project_Portfolio/node_modules/mysql/lib/protocol/Protocol.js:52:23)
at Connection.connect (/Users/narenpalep/Desktop/javascript/Project_Portfolio/node_modules/mysql/lib/Connection.js:130:18)
at Object.<anonymous> (/Users/narenpalep/Desktop/javascript/Project_Portfolio/db/db.js:11:12)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
Error: connect ETIMEDOUT
Try running with the below code also check the connection and for the right IP. There might be internal firewall block between the server and the system
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});

How to provide SERVICE_NAME in the connection options in mysql npm?

I have a JDBC connection string something like this
jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=OFF)(ADDRESS=(PROTOCOL=TCP)(HOST=hostname)(PORT=1711))(ADDRESS=(PROTOCOL=TCP)(HOST=hostname)(PORT=1712)))(CONNECT_DATA=(SERVICE_NAME=servicename)(SERVER=DEDICATED)))
I have created the connection as
var connection = mysql.createConnection({
host: "hostname",
port: "1711",
user: "user",
password: "password"
});
How do I also provide SERVICE_NAME (like the jdbc string) to the connection options?
I am getting the following error without it:
Error: connect ECONNREFUSED <some_ip>:1711
at Object.exports._errnoException (util.js:1028:11)
at exports._exceptionWithHostPort (util.js:1051:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)
--------------------
EDIT:
Changing the port to 1712 gives me a different error after taking a lot of time.
Error: Connection lost: The server closed the connection.
at Protocol.end (..\node_modules\mysql\lib\protocol\Protocol.js:113:13)
at Socket.<anonymous> (..\node_modules\mysql\lib\Connection.js:109:28)
at emitNone (events.js:91:20)
at Socket.emit (events.js:186:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
EDIT: Sorry. I didn't see the database was oracle and started trying mysql directly.
I am assuming that your mysql server is running on port 1711 not default port.
And if you are getting Connection lost error mean there are something wrong on your network try to reconnect your server after sometime.
var conn;
function handleDisconnect() {
conn = mysql.createConnection(//your config);
conn.connect(function(err) {
if(err) {
console.log('error when connecting to database:', err);
setTimeout(handleDisconnectConnection, 5000);
}
});
connection.on('error', function(err) {
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') {
handleDisconnectConnection();
} else {
throw err;
}
});
}
handleDisconnectConnection();
Hope that will work for you

unable to connect mysql in node js

my script is here
var mysql= require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '12345',
database: 'mydb'
});
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
when i running this code it shows this error
error connecting: Error: connect ETIMEDOUT
at Connection._handleConnectTimeout (~/node_modules/mysql/lib/Connection.js:414:13)
at Socket.g (events.js:180:16)
at Socket.EventEmitter.emit (events.js:92:17)
at Socket._onTimeout (net.js:327:8)
at Timer.unrefTimeout [as ontimeout] (timers.js:412:13)
--------------------
at Protocol._enqueue (~/mysql/lib/protocol/Protocol.js:141:48)
at Protocol.handshake (~/node_modules/mysql/lib/protocol/Protocol.js:52:41)
at Connection.connect (~/node_modules/mysql/lib/Connection.js:125:18)
at Object.<anonymous> (~/Desktop/Node-Eclipse/server.js:10:12)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
Username and password and all other details are correct
I'm using an export that works exactly like your function and it works properly..
var mysql = require("mysql");
var self = module.exports = {
db:{},
init: function(login, callback) {
self.db = mysql.createConnection({
host:'myHost',
user:'myUser',
password:'myPassword',
database:'myDbName'
});
return self.db.connect(function(err) {
if (err) {
callback(null);
}
else {
callback(self.db);
}
});
},
execute:function(login, request, callback) {
return self.db.query(request, function(err, rows, fields) {
if (err) {
callback(null);
}
else {
callback(rows);
}
});
}
};
Please pass port number which is 3306 in your mysql connection