24

Once in a while, my Ajax calls (via JQuery 1.8) in my application are stuck with status "pending" for a long time (sometimes up to 17 minutes). I've googled it and all possible solutions didn't work:

  1. I have no ad blocker installed.
  2. I've disabled the "predict network actions to improve page load performance" flag in Chrome.
  3. I've also added a query string to the Ajax call to make it unique (to disable any Chrome cache locking).

Do you have a any idea how to solve this?

In the example below, the request was pending for 17 minutes (verified with Fiddler that it was sent only after 17 minutes).

   GET http://www.mywebsite.com/foo/rest/publishers/1/packages?_=1421584749323    HTTP/1.1
   Host: www.mywebsite.com
   Connection: keep-alive
   Accept: application/json, text/javascript, */*; q=0.01
   X-Requested-With: XMLHttpRequest
   User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36    (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
   Content-Type: application/json
   Referer: http://www.mywebsite.com/foo/client/home
   Accept-Encoding: gzip, deflate, sdch
   Accept-Language: en-US,en;q=0.8,he;q=0.6,ru;q=0.4
   Cookie: JSESSIONID=C668509B5AFCDEBE9C9774C4721AFB9D;
   aaassz="ddss"

See image: https://drive.google.com/file/d/0B9uQiZLJG1csNzlPcHZEWHl1Z2c/view

ouflak
  • 2,458
  • 10
  • 44
  • 49
Wasafa1
  • 785
  • 2
  • 10
  • 21
  • Do you have a polling cycle? I had this problem too, because there were to many requests (50 for 1,5 sec.). So, chrome was waiting until they done, and only after that (26 sec. later) treated latest request, even though it takes only 0.1 sec. – Ivan Ivanov Jan 21 '15 at 07:21
  • I have a polling cycle every 5 minutes. However, we don't see how it justifies 17 minutes stalling of Chrome. did reducing the polling interval solved your problem? – Wasafa1 Jan 22 '15 at 19:41
  • Per chrome's explaination, The stalled time is the time the request spent waiting before it could be sent. This time is inclusive of any time spent in proxy negotiation. Additionally, this time will include when the browser is waiting for an already established connection to become available for re-use, obeying Chrome's *maximum six TCP connection per origin rule*. – Sablefoste Apr 28 '15 at 16:13
  • I was getting the same pending message when I was issuing a request, In my case there was some problem with the data that I was receiving form the server side, I've selected a new anonymous type (with C# and LINQ) instead of whole model and send it, and it worked, I don't know why though. – Hamid Mosalla Feb 25 '16 at 12:24
  • if one of your services don't complete the request and sends a response, you would eventually end up with all your ajax request pending. look into the first service that give you a pending status. – Skvettn Feb 28 '17 at 10:59

6 Answers6

8

I have stumbled on exactly the same problem. As soon as I disabled:

Use a prediction service to load pages more quickly

Go Advanced Settings -> Privacy -> ca. 3rd checkbox, everything started to work as it should. I was unable to reproduce the error.

The jquery/ajax poller works perfectly in Firefox. It's only Chrome - tested on Linux & Windows.

It is not a perfect solution, as it won't affect users in the global sense - but maybe you are in the same situation as I - limited audience.

Gustavo Morales
  • 2,614
  • 9
  • 29
  • 37
michael
  • 81
  • 1
  • 2
  • This seems to fix the problem for me as well. – kristinalim Dec 12 '16 at 02:31
  • This did not make any difference in my case, but interesting hypothesis. Simply put Chrome limits the number of outstanding requests for each tab/session to 6 so maybe there are other things going on in the background that isn't showing up in the network monitor in dev tools within Chrome. – kashiraja Aug 03 '17 at 16:19
4

You can try this.

NOW UPDATED WITH ACTUAL WORKING CODE

(used some timezone code of my own so excuse the references to timezone)

First initialize arrays and run your request counting logic

var request = ( typeof request != 'undefined' && request instanceof Array ) ? request : [];
var pendingAjax = ( typeof pendingAjax != 'undefined' && pendingAjax instanceof Array ) ? pendingAjax : [];

Use .ajaxStart and .ajaxStop to keep track of the active requests.

var ajaxActive = 0;
$( document ).ajaxStart(function() {
  ajaxActive++;
  document.ajaxQueueFull = ajaxActive > 5;
});
$(document).ajaxStop(function() {
  ajaxActive--;
  document.ajaxQueueFull = ajaxActive > 5;
}

Create a function to build new requests

    function ajaxRequestNew(t, u, d, s) {

        var instance = request.length + 1;
        request[instance] = $.ajax({
            method: t,
            url: u,
            data: {ajaxPost: d },
            success: s
        });
        return instance;
    }

Now create your request getting the instance number returned

    var instance = ajaxRequestNew('POST', 
                                  'js/ajax_timezone.php', 
                                  { ajaxAction : "ajaxGetTimezone", 
                                    tzoffset : "0", 
                                    tztimezone: "America/New_York" },
                                    function(data) {  }
    );

The $.ajax() function returns a XMLHttpRequest object. So we use a while loop to check when our ajax actually gets sent and aborts other active requests if the request is stalled.

    while(request[instance] === null || (request[instance].readyState < 1 || request[instance].readyState > 4)) {
        if (document.ajaxQueueFull) {
            //abort existing requests
            $.each(request, function(i,v) {
                if (i !== instance) {
                    request[i].abort();
                }
            });
        }
    }

Push your request onto the stack

    pendingAjax.push(request[instance]);

Create callbacks for your request

  var timezoneFailCallback = function(data) {
        console.log('fail');
        console.dir(data);
    };

    var timezoneSuccessCallback = function(data) {
        console.log('success');
        console.dir(data);
    };

use when to apply the callbacks

    $.when.apply($, pendingAjax).done( timezoneSuccessCallback ).fail( timezoneFailCallback);

The code may need a little tweaking for your app, but hopefully you get the idea. Let me know if you have any questions.

Tech Savant
  • 3,686
  • 1
  • 19
  • 39
  • 1
    This would fix the issue if a request on a particular endpoint stalls, but what if all requests are stalled, regardless of endpoint? In my case Chrome only initiates a request once per second when it goes into this state (maybe Chrome is throttling the requests because the application is sending too many at a time, sort of to limit what Chrome thinks is a badly behaving app)? – kashiraja Aug 03 '17 at 16:17
3

I know this is an old thread but I'm posting this for people that are scrambling to find some sort of answer for this. I had to deal with this head scratcher as well. My problem was due to Ad-blocker blocking an API call that had the word "coupon" in it. It was blocking the request while keeping it alive. after few blocks every request would automatically go to pending status since there were too many (I think around 6 or 7) live requests.

Type chrome://net-internals/#events in your chrome address bar to inspect requests. That will give you a clearer overview of the problem. I attached two images that I captured While I was trying to figure this out.

debugger screenshot

net-internal screenshot

2

If you are in control of server side, this might be applicable to your case: Add to server's response headers[ 'Connection' ] = 'close' In my case 'keep-alive' was the reason for the problem

vladbph
  • 131
  • 6
0

After three days of headache, I realized I was calling a database backup function in the middle of a Mysql transaction.

ouflak
  • 2,458
  • 10
  • 44
  • 49
Gatimu
  • 1
0

May be use setTimeout.

Try use this

function ReadServer() {
    handleTimeInfo = setTimeout(function run() {
        /*You function pennding server*/
        TimerInfo();
    }, 60*1000);
    

function TimerInfo(){
    handleTimeInfo = setTimeout(function run() {ReadServer();}, 60*1000);           
}