Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

request callback not called on socket error #324

Closed
ashelley opened this issue Oct 13, 2015 · 4 comments
Closed

request callback not called on socket error #324

ashelley opened this issue Oct 13, 2015 · 4 comments

Comments

@ashelley
Copy link
Contributor

Hello,

When a socket error occurs the request callback is never called. I've created a proof of concept patch to show how to work around the issue. The goal of this patch is to ensure that when a request exists on the connection the connection should ensure that the request callback gets called.

ashelley@a9ef6e2

@@ -1055,7 +1055,10 @@ Connection.prototype.STATE = {
   SENT_CLIENT_REQUEST: {
     name: 'SentClientRequest',
     events: {
-      socketError: function() {
+      socketError: function(err) {
+        const sqlRequest = this.request;
+        this.request = void 0;
+        sqlRequest.callback(err);
         return this.transitionTo(this.STATE.FINAL);
       },
       data: function(data) {

Here is my test code to show that the callback is never called:

var tedious = require('tedious');
var Request = tedious.Request;
var Connection = tedious.Connection;

var poolConfig = {
    min: 2,
    max: 4,
    log: function(text) {
        console.log('log', text);
    }
};

var sqlConfig = {
    userName: process.env.SQL_USER,
    password: process.env.SQL_PASS,
    server: process.env.SQL_HOST,
    options: {
        port: process.env.SQL_PORT,
        database: process.env.SQL_DATABASE,
        requestTimeout: 0
    }
};

var counter = 0;

function getConnection(done) {
    counter++;
    var connection = new Connection(sqlConfig);
    connection.on('connect', function(err) {
        done(err, connection);
    });
    connection.on('error', function(err) {
        console.log('connection error', err);
    });
}

function execSql(connection, sql, done) {
    var request = new Request(sql, done);
    connection.execSql(request);
}

function start() {
    getConnection(function(err, connection) {
        if (err) {
            console.log('error acquiring connection', err);
            return next();
        }
        console.log('querying');
        execSql(connection, "WAITFOR DELAY '00:01';\nSELECT NEWID();", function(err, rowCount) {
            if (err) {
                console.log('error executing query', err);
                return next();
            }
            console.log('success', rowCount);
            next();
        });
    });
}

function next() {
    console.log('next');
    setTimeout(function() {
        start()
    }, 5000);
}

start();

While running the above program after I see it start querying I block the port to simulate a socket error:

# iptables -A OUTPUT -p tcp --dport $SQL_PORT -j DROP
@lee-houghton
Copy link
Contributor

Interesting, this could well be the source of the resource leak woes I've been having in production. I'll try it out and report back sometime tomorrow hopefully.

@ashelley
Copy link
Contributor Author

fyi, i think the patch should be:

       socketError: function(err) {
         const sqlRequest = this.request;
         this.request = void 0;
         sqlRequest.callback(err);
         return this.transitionTo(this.STATE.FINAL);
       },

made an error with what version i pushed, it wasn't passing along the socket error

@bretcope
Copy link
Member

Would you mind turning your patch into an actual pull request? Also, adding a test to the test suite would be helpful.

@ashelley
Copy link
Contributor Author

hello @bretcope I have created a pull request and added a simple test here:

#325

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants