Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
474 views
in Technique[技术] by (71.8m points)

ajax - Is it possible to receive out-of-order responses with HTTP?

Sec 8.1.2.2 Pipelining says:

"A server MUST send its responses to requests in the same order that the requests were received".

So, I thought, if I send out multiple AJAX requests from my browser, they will still be processed in the order in which they were received by the server.

But then, I was reading this post from Alex Maccaw, where he states :

"The last issue is with Ajax requests that get sent out in parallel. If a user creates a record, and then immediately updates the same record, two Ajax requests will be sent out at the same time, a POST and a PUT. However, if the server processes the 'update' request before the 'create' one, it'll freak out. It has no idea what record needs updating, as the record hasn't been created yet.

The solution to this is to pipeline Ajax requests, transmitting them serially. Spine does this by default, queuing up POST, PUT and DELETE Ajax requests so they're sent one at a time. The next request sent only after the previous one has returned successfully."

So, how can I programmatically create the scenario that Alex Maccaw mentions ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think in short, the answer to your question is "yes".

HTTP 1.1 does not forbid opening multiple TCP connections to the same server (in fact it recommends two), and all modern browsers do so (in fact, most do six or more). See Max parallel http connections in a browser? . A request-response cycle can be going on on each of those connections, and some of the request-response cycles can be much faster than others, for various reasons. Network congestion, complexity of the request, speed of and load on the particular "worker" your request is processed by, etc. This means that a request-response cycle for a request started later could easily finish sooner than a cycle for a request started earlier.

"A server MUST send its responses to requests in the same order that the requests were received".

This statement solely applies to pipelining multiple http requests, i.e. sending multiple requests over one TCP connection, without waiting for a response for each request. It does not apply to opening multiple TCP connections to the same server.

Normally, you have only one request per tcp connection going on at the same time. The client waits for response, and when it gets response, perhaps reuses the connection for a new request. Thus, as far as regular (non-pipelined) http is concerned, there isn't even a concept of "order of responses", because there's only a single request-response cycle going on on a TCP connection.

With pipelining, multiple http requests are fired of on one TCP connection. It's important to get the responses back in order, because that's the way responses are matched to their original requests. (Matching responses to requests could have been done differently, for example by providing a hash of the full request on each response or so, but that's beside the point).

Also, it's good to know that (default) support for HTTP pipelining is not broad. Chromium project is reluctant about enabling it: https://insouciant.org/tech/status-of-http-pipelining-in-chromium/ . Firefox still doesn't have it enabled either. https://bugzilla.mozilla.org/show_bug.cgi?id=264354

Apple on the other hand has enabled support for it in safari on IOS5, probably because request-response latency on mobile is a bigger problem. http://www.guypo.com/mobile/ios5-top10-performance-changes/ Android stock browser does too. At least the pre-Chrome version. http://www.guypo.com/mobile/http-pipelining-big-in-mobile/

Alex Maccaw wrote in the post about Spine you cite:

The solution to this is to pipeline Ajax requests, transmitting them serially.

I think the term pipeline is somewhat confusing in this context. First of all, the "pipelining" that Spine does is something wholly different than the possibility of pipelining requests in HTTP. Secondly, I think I'd call this particular feature of Spine request queuing. Spine queues requests, and processes the items in the queue in order they were added.

In general, I think the term "pipelining" is best used for when things are made purposively faster, while "queuing" is best used when making things purposively slower (to prevent race conditions, or to lighten load on the processor of the queued items, for example).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...