M
M
mental_attack2014-12-03 13:01:26
Node.js
mental_attack, 2014-12-03 13:01:26

Node.js+ajax+long sql query. Why is the data not reaching the client?

The application is a report generator based on data received from MS SQL SERVER.
An ajax request is made on the client to the server. The server launches a sql query to the whine, receives the data, serializes it to json and sends it to the client. The client generates a table based on the response data and displays it on the page.
Faced with the fact that the sql-query is running too long (about 4 minutes).
If I access the site via nginx, then 2 minutes after sending ajax, I get an alert "Error error: Bad Gateway", and if I access the site via localhost: port, i.e. bypassing nginx, I get an alert "error error: error".
at the same time, the following entry is output to the console:
GET /result?IP=10.10.10.7&CODE=12&START=12/02/2013&END= 12/02/2014 200 120618ms
status 200!!!
although the execution time is 2 minutes + - a couple of seconds, the actual sql query still continues to work. This becomes clear because after a couple of minutes,
console.log("SerializeToJSON"); records are displayed in the same console below.
and
console.log("SendClient");
from the respective functions. But by this time, it feels like the client feedback through the res object has already been lost, and as a result res.end(jsonData); goes nowhere.
who has any thoughts on this? I do not know where else to dig and what to check?
If you reduce the execution time of the sql query and, accordingly, the amount of data received, by selecting query arguments, then everything works.
To open a connection and execute a request, I use the odbc module
inThe documentation does not say anything about timeouts for query execution.
I tried to set a timeout in the connection string like this:
var Connect = "Driver={SQL Server};Server=" + ip + ";Database=MyDB;UID=sa;PWD=password;command timeout=600000;";
did not help.
this is the server side code, ajax handler:

exports.result = function(req, res, curSessionId) {
    var params = new Params(
        req.param("IP"),
        req.param("CODE"),
        req.param("START"),
        req.param("END")
    );

 GetData(res, params, function(data) {
        SerializeToJSON(data, function(jsonData) {
            SendClient(res, jsonData);
        });
    });
}

 function GetData(res, params, callback) {
    var i = 0;
    var ip = params["p_IP"];
    var code = params["p_CODE"];
    var Start = params["p_START"];
    var End = params["p_END"];
    var tmpConnect = "Driver={SQL Server};Server=" + ip + ";Database=MyDB;UID=sa;PWD=password;command timeout=600000;";

    odbc.open(tmpConnect, function(err, tmpDB) {

        if (err) {
            return console.log("Error!\n" + err.message);
        }

        var SQL = "SELECT * FROM [dbo].[ufn_getJornalRealizNew]('" + Start + "', '" + End + "', '" + code + "')";

        tmpDB.query(SQL, function (err, rows, moreResultSets) {

            if (err) {
                return console.log("Error!\n" + err.message);
            }

            tmpDB.close();
            callback(rows);
        });
    });
 }

 function SerializeToJSON(data, callback) {
    var jsonData = JSON.stringify(data);
    console.log(SerializeToJSON);
    callback(jsonData);
 }

 function SendClient(res, jsonData) {
    console.log(SendClient);
    res.end(jsonData);
 }

 function Params(ip, code, Start, End) {
    this.p_IP = ip;
    this.p_CODE = code;
    this.p_START = Start;
    this.p_END = End;
 }

and here is the ajax code on the client:
function QueryItem(ip, code, Start, End) {
        document.getElementById('btn').innerText = "Подождите...";
       //alert(ip + "@" + code + "@" + kad + "@" + Start + "@" + End);
        content = $.ajax({
            url: '/result',
            type: 'get',
            timeout: 600000,
            data: ({IP: ip, CODE: code, START: Start, END: End}),
            success: function(msg) {
                alert("Ответ от сервера получен!");
                SetTable(msg);
                document.getElementById('btn').innerText = "Сформировать"
            },
            error: onAjaxError
        }).responseText;
        return;
    }

var onAjaxError = function(xhr, status){
        //showLoading(false)
        var errinfo = { errcode: status };
        if (xhr.status != 200) {
            // может быть статус 200, а ошибка
            // из-за некорректного JSON
            errinfo.message = xhr.statusText;
        } else {
            errinfo.message = 'Некорректные данные с сервера';
        }
        onLoadError(errinfo);
}

var onLoadError = function(error) {
        var msg = "Ошибка "+error.errcode;
        if (error.message) msg = msg + ' :'+error.message;
        return alert(msg);
}

The server is based on the Express module:
var express = require('express');
var app = express();

http.createServer(app).listen(config.get('port'), function(){
  console.log('Express server of the REPORTS project listening on port ' + config.get('port'));
});

Could it be that node (or someone else) is closing the connection to the client after 2 minutes? Maybe some timeouts in the node should be specified?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
O
Oleg ak-o, 2014-12-03
@ak-o

I don't really understand the topic, but by analogy with php I can say:
If the page wait is longer than the timeout in the browser, and the browser does not receive any data, the connection is interrupted. In php, I solved the issue by outputting "emptiness" ( echo ''; ) and clearing the buffer. The browser received this "nothing" and waited for the job to complete. Maybe you have a similar situation. How to proceed in the case of ajax\node.js unfortunately no ideas.
And I also thought: maybe the serialization of data from mysql in total with the request exceeds the timeout.

M
mental_attack, 2014-12-03
@mental_attack

> serialization of the data from mysql in the sum with request exceeds a timeout can.
only execution of one sql-query already exceeds apparently timeout.
question: what timeout is exceeded? how to set server response timeout in chrome? and is it possible at all? in the connection: keep-alive headers, if anything ...
UPD:
I can’t answer the comments for some reason, so I’ll edit it here:
In response to the comments ak-o:

ak-o: nginx is only used for proxying. I may not have written clearly ... but the sql query was not completed in 2 minutes. That's how it goes! The client sent an ajax request to the web server, the web server launched an sql query to the database, which takes about 4 minutes. After 2 minutes have elapsed since the ajax request was sent from the client to the web server, I get an error, but in fact the web server is still working, the sql request continues to be executed and after some time it works, returning a data set from the database , after that, the serialization of this data is started and the serialized data is sent to the client, but in fact the data goes nowhere! Because it looks like the connection between the web server and the browser has already been broken (after all, there was an error). The error is generated by the error handler in the ajax request. The question of why and who breaks the connection bothers me. )) Thanks for the advice, I'll try it. Likely, someone has already encountered a similar problem, but nothing has been found on Google to solve it. (
Tried without sql query. Set setTimeout to 3 minutes. The picture is the same. After 2 minutes, an error, after another minute, sending a response to nowhere.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question