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 ?
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).
They will not be handled synchronously unless the WebServer only has 1 thread to handle the requests which may only happen intentionally (possibly under a dev environment). Most of the time the Web server has hundreds of threads available to process requests as they come in and as 1 request may take longer than another, the responses can come back out of order. This is why it is called A(asynchronous)JAX.
1 request could take a full second to respond, while request 2 and 3 take 25ms to respond, thus the 1st request response comes in after both the 2nd and 3rd requests.
You can force a synchronous cycle but at the cost of everything stopping until the request is returned and processed, (Even JS loading spinners would stop).
See this article on forcing synchronous (SJAX) requests. http://www.hunlock.com/blogs/Snippets:_Synchronous_AJAX
RFC 2616 uses the term "pipelining" to refer to this:
- HTTP requests and responses can be pipelined on a connection.
Pipelining allows a client to make multiple requests without
waiting for each response, allowing a single TCP connection to
be used much more efficiently, with much lower elapsed time.
So pipelining here means using a persistent HTTP connection to make multiple requests. This is functionality that has to be supported by the browser, and currently it is either unsupported or off by default for pretty much every browser. So right now, when you make a number of plain AJAX requests there is always the possibility that responses will return out of order.
Most of the time this is not a problem. When it is, you can take appropriate measures to "pipeline" the requests manually; they still go out on separate connections, but your code is engineered to wait until a pending request has completed before issuing the next one. In the article you link to, this functionality is built into Spine.