Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 332
2020 Avatar asked Apr 29 '13 20:04

2020


People also ask

Can a HTTP request have multiple responses?

A HTTP request can have multiple 'responses', but the responses all have statuscodes in the 1xx range, such as 102 Processing. However, these responses are only headers, never bodies. HTTP/1.1 (like 1.0 before it) is a request/response protocol. Sending a response unsolicited is not allowed.

How do HTTP responses work?

HTTP requests work as the intermediary transportation method between a client/application and a server. The client submits an HTTP request to the server, and after internalizing the message, the server sends back a response. The response contains status information about the request.

Does every HTTP request have a response?

Irrespective of the HTTP method (GET, POST, HEAD, etc.) you use to make a request to the server, the server always responds in the same way (which has nothing to do with your request method); of course content of response is changed depending on your request. So there's no such thing as POST or GET responses.

What is the difference between HTTP request and response?

HTTP messages are how data is exchanged between a server and a client. There are two types of messages: requests sent by the client to trigger an action on the server, and responses, the answer from the server.


2 Answers

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).

like image 139
Myrne Stol Avatar answered Oct 30 '22 18:10

Myrne Stol


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

like image 43
justadevguy Avatar answered Oct 30 '22 18:10

justadevguy