0
votes

I build a rest api with NodeJS. It is using the modules cluster, express ,body-parser, mssql. The solution is working fine but sometimes the result is the sql error: The server closed the connection.

Does anyone know a solution. I read about mssql promise of the promise module but how does i implement this and is this a good solution.

When the database server gives the error: The server closed the connection i want automatic retry (Open SQL DB Connection and execute query).

var cluster = require('cluster');


if (cluster.isMaster) {


var cpuCount = require('os').cpus().length;


for (var i = 0; i < cpuCount; i += 1) {
    cluster.fork();
}


cluster.on('exit', function (worker) {

    // Replace the dead worker, we're not sentimental
    console.log('Worker %d died:', worker.id);
    cluster.fork();

});


} else {


var express = require("express");
var bodyParser = require("body-parser");
var sql = require("mssql");
var app = express(); 


app.use(bodyParser.json()); 


app.use(function (req, res, next) {
    //Enabling CORS 
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
    next();
});


 var server = app.listen(process.env.PORT || 8000, function () {
    var port = server.address().port;
    console.log("App now running on port", port);
 });


var dbConfig = {
    user:  "<USER>",
    password: "<PASSWORD>",
    server: "<SERVER>",
    database: "<DB>",
    connectionTimeout: 999999999,
    requestTimeout: 999999999,
    pool: {
            max: 20,
            min: 10,
            idleTimeoutMillis: 30000
        },
    options: {
            encrypt: true
        }
};


var  executeQuery = function(res, query){     

     sql.connect(dbConfig, function (err, connection) {
         if (err) {   
                     console.log("Error while connecting database :- " + err);
                     res.send(err);
                     res.end();
                  }
                  else {

                         var request = new sql.Request(connection);

                         request.query(query, function (err, rs) {
                           if (err) {
                                      console.log("Error while querying database :- " + err);
                                      res.send(err);
                                      res.end();
                                     }
                                     else {
                                            console.log("Result :- " + rs); 
                                            res.send(rs);
                                            res.end();
                                            }
                               });
                         sql.close();      
                       }
      }); 


}


 app.post("/ic/events/add", function(req , res){
                var query = "INSERT INTO EVENT VALUES ('FILE')";
                executeQuery (res, query);
});


 app.post("/ic/process/to", function(req , res){
                var query = "SELECT TOP 1 FROM EVENT WHERE STATUS = 0";
                executeQuery (res, query);
});

}

Kind regards,

Mark

2
But Cody G, The connection is only open when a query is executed and after the result i close the connection directly. Or do I miss something - Mark van der Steen
Sorry, I didn't read that closely! I see - Cody G
I hightly recommend async/await npmjs.com/package/mssql - Cody G
But how do I implement this in mine app? - Mark van der Steen
You follow the documentation; is there any place you're having trouble getting started? You can use async/await inside of an async function, so generally people have a (async function main(){})() they create and call which really fires off the rest of the application. There's some syntax and gotchyas to learn if it's the first time you're using it. - Cody G

2 Answers

0
votes

I will thank you for your help. I changed the app with the following code to use 1 connection. After 2 days running the app I don't have any connection closed error anymore.

//Initiallising connection string
var dbConfig = {
    user:  "",
    password: "",
    server: "",
    database: "",
    connectionTimeout: 999999999,
    requestTimeout: 999999999,
    options: {
            encrypt: true
        }
};



sql.connect(dbConfig, function (err, connection) {
         if (err) {   
                     console.log("Error while connecting database :- " + err);
                  }
            }); 


var  executeQuery = function(res, query, connection){     

                         // create Request object
                         var request = new sql.Request(connection);
                         // query to the database
                         request.query(query, function (err, rs) {
                           if (err) {
                                      console.log("Error while querying database :- " + err);
                                      res.send(err);
                                      res.end();
                                     }
                                     else {
                                            console.log("Result :- " + rs); 
                                            res.send(rs);
                                            res.end();
                                            }
                               });


      }; 
-1
votes

Do not open a connection for every query executed. Open a connection to the database when the server starts up and use that connection for the lifetime of the app.

Here's an article on sharing the database connection throughout the app.

Now, if there is a disconnect at anytime while querying, then log the error to a logging system (Loggly, Rollbar), let the app die and then have a node monitor restart the app (Forever, Nodemon). The error sent to the log might give you some answers as far as what the issue is. Most likely it is a network error and your database is not accessible.