0

I have a page that includes an AJAX polling request that fires off every 5 seconds as well as other AJAX CRUD operations that can take up to a minute to complete. What seems to be happening is the polling request executes and completes every 5 seconds except when a long running request is being processed - in these long running execution scenarios the beforeSend event of the polling request will fire, but it won't hit the controller until the long running request is complete. The polling requests just queue up and wait until the long running request is complete, at which point it will carry out the queued polling requests.

I have recreated the scenario within my existing solution (results below) using test methods and a 30 second thread sleep to mimic a long running DB transaction. You will notice that when the TestSlowMethod30Seconds() begins the TestRequest() calls start to queue up and only once the TestSlowMethod30Seconds() is complete do the TestRequest() calls complete.

If I create a fresh solution using a basic MVC VS template and do the same thing it works as expected and the long running request has no impact on other requests - they are all handled completely asynchronously.

I have spent the whole day on this testing and I can't for the life of me work out what the issue in my existing solution is.

Does anyone have any ideas?

enter image description here

var ajaxTest = namespace("test.ajaxTest");

ajaxTest.init = function () {
    window.setInterval(function () {
        ajaxTest.TestRequest();
    }, 5000);
};


ajaxTest.TestRequest = function () {
    $.ajax({
        type: "POST",
        url: "/Test/TestRequest",       
        beforeSend: function () {
            console.log("*** TestRequest() begin");
        },
        complete: function () {
            console.log("*** TestRequest() complete");
        }           
    });
};

// this method is called from a button click event
ajaxTest.TestSlowMethod30Seconds = function () {    
    $.ajax({
        type: "POST",
        url: "/Test/TestSlowMethod30Seconds",       
        beforeSend: function () {
            console.log("*** TestSlowMethod30Seconds() begin");
        },
        complete: function () {         
            console.log("*** TestSlowMethod30Seconds() complete");
        }           
    });
};

MVC Test Controller

public ActionResult TestRequest()
{
    return Json("Success");
}

public ActionResult TestSlowMethod30Seconds()
{
    System.Threading.Thread.Sleep(30000);

    return Json("Success");
}
Mark Erasmus
  • 2,305
  • 6
  • 25
  • 37

2 Answers2

2

Session state. If your requests are using session state then the requests will be serialized. If you don't want them to be serialized then your server side code will need to run without session state or be marked as only using read only session state

Mike
  • 3,462
  • 22
  • 25
  • The requests are not using session state. As you can see above the controller methods are pretty much as simple as they can get. – Mark Erasmus Oct 09 '14 at 19:27
  • If this is asp.net I believe they will default to using session state even if you are not using it in the controller – Mike Oct 09 '14 at 19:34
  • You're spot on! By decoration the controller with [SessionState(SessionStateBehavior.ReadOnly)] made it work. I was wondering why then my fresh MVC test app was working without having to set the session state behaviour, but when I tested by adding something to session in the controller resulted in the same behaviour – Mark Erasmus Oct 09 '14 at 23:05
0

You are probably hitting the maximum number of parallel connection limit for your browser:

Max parallel http connections in a browser?

You need to reduce the number of concurrent requests - keep only one long pooling request or switch to other technology like web-sockets or server side events.

Also there is a useful library called signalr

BTW: try to open more tabs, you will notice more lagging

Community
  • 1
  • 1
Marian Ban
  • 8,158
  • 1
  • 32
  • 45
  • I don't see how this can be the issue. If I strip out the layout page to the bare bones it's just two test requests that are trying to execute. – Mark Erasmus Oct 09 '14 at 19:26
  • @MarkErasmus from your log: you start 1 long request then 6 test requests (one or two (i'm not sure) test request will wait for the long request to finish). – Marian Ban Oct 09 '14 at 19:34
  • @MarkErasmus Try to open more then 6 long requests, you will notice that the requests (7,8) will wait for the previous to finish – Marian Ban Oct 09 '14 at 19:38
  • 1
    @MarkErasmus also check Mikes answer and try to decorate your controller with [SessionState(SessionStateBehavior.ReadOnly)] – Marian Ban Oct 09 '14 at 19:52