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

Invalid state; requests can only be made in the LoggedIn state, not the SentClientRequest state #19

Closed
rgarrison3 opened this issue Mar 7, 2012 · 10 comments

Comments

@rgarrison3
Copy link

This issue arises when calling one request then refreshing the page. I have the code that I have wrote for this if anyone is interested in duplicating it.

http://c9754731.r31.cf2.rackcdn.com/WebServicesServlet_Exam.zip

All you have to do to set this up (I built it and use it on windows so I dont know how it will work on linux lol). You just need to setup the ConnectionConfig.js file in the lib folder with your connection info and then modify the gateway test method.

Any help with this would be greatly appreciated!!!

@pekim
Copy link
Collaborator

pekim commented Mar 8, 2012

I'm sorry, I've not had time to look at this yet. I'll take a look at the weekend.

@pekim
Copy link
Collaborator

pekim commented Mar 9, 2012

I've recreated the problem with your code, and I think that I understand the problem.

The error that is reported, Invalid state; requests can only be made in the LoggedIn state, not the SentClientRequest state, indicates that there has been an attempt to execute a second request on a connection while one is already in progress. Concurrent requests (on a single connection) are not supported. This should probably be made clearer in the documentation.

Your code always causes this problem on the second request. Each page request results in a call to this code.

controller.execute = function(session, admin, sqlCommand) {
    var MSSqlConnection = require('./MSSqlConnection');

    MSSqlConnection.on('connected', function(connection){
            _performQuery(connection, sqlCommand.toString());
    });

    ...
}

Your MSSqlConnection variable is a singleton, because require caches modules. So when this code is called for the second page request, a second listener is added for the MSSqlConnection's connected event. When the connected event is emitted from MSSqlConnection, both listeners are called. This results in two calls to the Tedious Connection object's execSql function. The second call occurs before the first request has completed, and the state machine in Connection detects and reports the problem.

I will leave the issue open until I have updated the documentation to make it clear that only one request can be performed on a connection at a time.

@pekim
Copy link
Collaborator

pekim commented Mar 9, 2012

Documentation updated.

commit 6eb911a

@pekim pekim closed this as completed Mar 9, 2012
@kenperkins
Copy link

Here's the problem with this issue: There's no signal in the code (such that I can see) as to when I can successfully call again.

I'm trying to make multiple queries in a row, and even if I wait for request.end before calling the next, I'm still running into this error.

Edit: oops. As it turned out I had accidentally called my callback in the callback of the request without checking if it was an error.

Disregard!

@pekim
Copy link
Collaborator

pekim commented Apr 15, 2012

You made me realise that the documentation doesn't make it clear enough that the Request's callback signifies the completion of the request, and that another request may not be made until it is called. As a result I've updated the documentation to make it clearer.

@hasan3ysf
Copy link

Hi,
I understood the above clearly, and tried to stick to it in my application.
The code below, do the following:

  1. Every 1 second, fetsh the data from the server (fetchStock function) and save it in temporary array,
  2. Every 1 second, send the data saved in the temporary array to the client using the Server-Sent Events (SSE) API.

It looks the 1 second, is not enough, so I got getting the error mentioned here, many times, so i increased it to 5 second, but still git it from time to time.

Is there a way to use Promise().then to be sure the fetchStock function is not re-called before the first call be completely executed.

var Request = require('tedious').Request;
var Connection = require('tedious').Connection;
var config = {
     userName: 'sa',
     password: 'pswd',
    server: 'xx.xxx.xx.xxx',
    options: {
        database: 'DB',
             rowCollectionOnRequestCompletion: 'true',
             rowCollectionOnDone: 'true'
     },
 };
var sql = new Connection(config);

var addElem = (obj, elem)=> [].push.call(obj, elem);
var result = {}, tmpCol = {}, tmpRow = {};
module.exports = {

  displayStock: function (es) {
      var dloop = setInterval(function() {
      if(result.error !== null)
            if (es) es.send(JSON.stringify(result), {event: 'rmSoH', id: (new Date()).toLocaleTimeString()});
      if(result.error === null)
            if (es) es.send('connection is closed');
      }, 1000);
  },

  fetchStock: function () {
            request = new Request("SELECT ItemCode, WhsCode, OnHand FROM OITW where OnHand > 0 and (WhsCode ='RM' or WhsCode ='FG');", function(err, rowCount, rows) {
            if (err) {
            result = {'error': err};
            console.log((new Date()).toLocaleTimeString()+' err : '+err);
             }
             if(rows)
             rows.forEach(function(row){
                 row.forEach(function(column){
                     var colName = column.metadata.colName;
                     var value = column.value;
                     addElem(tmpCol, {colName: value})
                 });
             addElem(tmpRow,{'item': tmpCol[0].colName, 'Whs': tmpCol[1].colName, 'Qty': tmpCol[2].colName});
             tmpCol = {};
           });
           result = tmpRow;
           tmpRow={}
       });
    sql.execSql(request);
  }
}

@swapnilkadu
Copy link

I am still getting the same issue, please look at the code below:

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

var config2 = {
    userName: 'dbuser',
    password: 'dbpass',
    server: 'mysqlserver.com',
    options: {
        database: 'msdb'
    }
};

var connection = new Connection(config2);
    connection.on('connect', function(err) {
        if(err) {
            console.log("Database connection is not established: \n"+err);
            process.exit(0);
        } else {
            console.log("Connected");  // If no error, then good to proceed.
            createTableOperation();
        }
    });  

function createTableOperation() {
    var query = "CREATE TABLE ClientDetailsTest(CLIENT_ID CHAR(5) PRIMARY KEY, CLIENT_NAME VARCHAR(25), CLIENT_CHANNEL VARCHAR(25))";

    request = new Request(query, function(err){
        if(err) {
            console.log("Error while creating table: "+err);
            process.exit(0);
        }
    });
    connection.execSql(request);
}

@arthurschreiber
Copy link
Collaborator

@swapnilkadu What error are you seeing exactly? Do you see any of the console.log statements?

@pshah222
Copy link

pshah222 commented Aug 7, 2017

I am wondering how the above issue of @swapnilkadu fixed? I am having the same issue. Any pointers?

@LakMoore
Copy link

Comment out the
connection.execSql(request);
as it will probably be masking the true error (which in my case was bad credentials).

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

8 participants