Note that there are some explanatory texts on larger screens.

plurals
  1. POChrome not handling jquery ajax query
    text
    copied!<p>I have the following query in jquery. It is reading the "publish" address of an Nginx subscribe/publish pair set up using Nginx's long polling module. </p> <pre><code>function requestNextBroadcast() { // never stops - every reply triggers next. // and silent errors restart via long timeout. getxhr = $.ajax({ url: "/activity", // dataType: 'json', data: "id="+channel, timeout: 46000, // must be longer than max heartbeat to only trigger after silent error. error: function(jqXHR, textStatus, errorThrown) { alert("Background failed "+textStatus); // should never happen getxhr.abort(); requestNextBroadcast(); // try again }, success: function(reply, textStatus, jqXHR) { handleRequest(reply); // this is the normal result. requestNextBroadcast(); } }); } </code></pre> <p>The code is part of a chat room. Every message sent is replied to with a null rply (with 200/OK) reply, but the data is published. This is the code to read the subscribe address as the data comes back. </p> <p>Using a timeout all people in the chatroom are sending a simple message every 30 to 40 seconds, even if they don't type anything, so there is pleanty of data for this code to read - at least 2 and possibly more messages per 40 seconds. </p> <p>The code is 100% rock solid in EI and Firefox. But one read in about 5 fails in Chrome. </p> <p>When Chrome fails it is with the 46 seconds timeout. </p> <p>The log shows one /activity network request outstanding at any one time.</p> <p>I've been crawling over this code for 3 days now, trying various idea. And every time IE and Firefox work fine and Chrome fails. </p> <p>One suggestion I have seen is to make the call syncronous - but that is clearly impossible because it would lock up te user interface for too long.</p> <p>Edit - I have a partial solution: The code is now this </p> <pre><code>function requestNextBroadcast() { // never stops - every reply triggers next. // and silent errors restart via long timeout. getxhr = jQuery.ajax({ url: "/activity", // dataType: 'json', data: "id="+channel, timeout: &lt;?php echo $delay; ?&gt;, error: function(jqXHR, textStatus, errorThrown) { window.status="GET error "+textStatus; setTimeout(requestNextBroadcast,20); // try again }, success: function(reply, textStatus, jqXHR) { handleRequest(reply); // this is the normal result. setTimeout(requestNextBroadcast,20); } }); } </code></pre> <p>Result is sometimes the reply is delayed until the $delay (15000) happens, Then the queued messages arrive too quicly to follow. I have been unable to make it drop messages (only tested with netwrok optomisation off) with this new arrangement. </p> <p>I very much doubt that delays are dur to networking problems - all machines are VMs within my one real machine, and there are no other users of my local LAN. </p> <p>Edit 2 (Friday 2:30 BST) - Changed the code to use promises - and the POST of actions started to show the same symptoms, but the receive side started to work fine! (????!!!???). This is the POST routine - it is handling a sequence of requests, to ensure only one at a time is outstanding. </p> <pre><code>function issuePostNow() { // reset heartbeat to dropout to send setTyping(false) in 30 to 40 seconds. clearTimeout(dropoutat); dropoutat = setTimeout(function() {sendTyping(false);}, 30000 + 10000*Math.random()); // and do send var url = "handlechat.php?"; if (postQueue.length &gt; 0) { postData = postQueue[0]; var postxhr = jQuery.ajax({ type: 'POST', url: url, data: postData, timeout: 5000 }) postxhr.done(function(txt){ postQueue.shift(); // remove this task if ((txt != null) &amp;&amp; (txt.length &gt; 0)) { alert("Error: unexpected post reply of: "+txt) } issuePostNow(); }); postxhr.fail(function(){ alert(window.status="POST error "+postxhr.statusText); issuePostNow(); }); } } </code></pre> <p>About one action in 8 the call to handlechat.php will timeout and the alert appears. Once the alert has been OKed, all queued up messages arrive. </p> <p>And I also noticed that the handlechat call was stalled before it wrote the message that others would see. I'm wondering if it could be some strange handling of session data by php. I know it carefully queues up calls so that session data is not corrupted, so I have been careful to use different browsers or different machines. There are only 2 php worker threads however php is NOT used in the handling of /activity or in the serving of static content. </p> <p>I have also thought it might be a shortage of nginx workers or php processors, so I have raised those. It is now more difficult to get things to fail - but still possible. My guess is the /activity call now fails one in 30 times, and does not drop messages at all.</p> <p>And thanks guys for your input. </p> <hr> <p>Summary of findings. </p> <p>1) It is a bug in Chrome that has been in the code for a while.<br> 2) With luck the bug can be made to appear as a POST that is not sent, and, when it times out it leaves Chrome in such a state that a repeat POST will succeed.<br> 3) The variable used to store the return from $.ajax() can be local or global. The new (promises) and the old format calls both trigger the bug.<br> 4) I have not found a work around or way to avoid the bug. </p> <p>Ian</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload