55
votes

I'm trying to implement long polling for the first time, and I'm using XMLHttpRequest objects to do it. So far, I've been successful at getting events in Firefox and Internet Explorer 11, but Chrome strangely is the odd one out this time.

I can load one page and it runs just fine. It makes the request right away and starts processing and displaying events. If I open the page in a second tab, one of the pages starts seeing delays in receiving events. In the dev tools window, I see multiple requests with this kind of timing:

screenshot

"Stalled" will range up to 20 seconds. It won't happen on every request, but will usually happen on several requests in a row, and in one tab.

At first I thought this was an issue with my server, but then I opened two IE tabs and two Firefox tabs, and they all connect and receive the same events without stalling. Only Chrome is having this kind of trouble.

I figure this is likely an issue with the way in which I'm making or serving up the request. For reference, the request headers look like this:

Connection: keep-alive
Last-Event-Id: 530
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

The response looks like this:

HTTP/1.1 200 OK
Cache-Control: no-cache
Transfer-Encoding: chunked
Content-Type: text/event-stream
Expires: Tue, 16 Dec 2014 21:00:40 GMT
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 16 Dec 2014 21:00:40 GMT
Connection: close

In spite of the headers involved, I'm not using the browser's native EventSource, but rather a polyfill that lets me set additional headers. The polyfill is using XMLHttpRequest under the covers, but it seems to me that no matter how the request is being made, it shouldn't stall for 20 seconds.

What might be causing Chrome to stall like this?

Edit: Chrome's chrome://net-internals/#events page shows that there's a timeout error involved:

t=33627 [st=    5]      HTTP_CACHE_ADD_TO_ENTRY  [dt=20001]
                --> net_error = -409 (ERR_CACHE_LOCK_TIMEOUT)

The error message refers to a patch added to Chrome six months ago (https://codereview.chromium.org/345643003), which implements a 20-second timeout when the same resource is requested multiple times. In fact, one of the bugs the patch tries to fix (bug number 46104) refers to a similar situation, and the patch is meant to reduce the time spent waiting.

It's possible the answer (or workaround) here is just to make the requests look different, although perhaps Chrome could respect the "no-cache" header I'm setting.

3
It says there's no issue with number 46104B T
Follow the BUG link with that number at the bottom of the issue I linked above.fluggo
Or let me see if I can link it directly now: code.google.com/p/chromium/issues/detail?id=46104fluggo
Is this the same as I experience here? Using Chrome 42 youtube.com/watch?v=PYorlA63ZzI&feature=youtu.be&hd=1nitech
In chrome 75.0.3770.100 non of the mentioned approaches worked - any ideas how to solve this issue?user3579222

3 Answers

48
votes

Yes, this behavior is due to Chrome locking the cache and waiting to see the result of one request before requesting the same resource again. The answer is to find a way to make the requests unique. I added a random number to the query string, and everything is working now.

For future reference, this was Chrome 39.0.2171.95.

Edit: Since this answer, I've come to understand that "Cache-Control: no-cache" doesn't do what I thought it does. Despite its name, responses with this header can be cached. I haven't tried, but I wonder if using "Cache-Control: no-store", which does prevent caching, would fix the issue.

2
votes

I have decided to keep it simple and checked the response headers of a website that did not have this issue and I changed my response headers to match theirs:

Cache-Control: max-age=3, must-revalidate
1
votes

adding Cache-Control: no-cache, no-transform worked for me