Reputation: 8619
I am a front end developer with limited knowledge of how networks work.
When Javascript's XMLHttpRequest times out the ontimeout handler is triggered.
Unless the XMLHttpRequest.timeout property is set (supported in modern browsers), the request waits for the browsers default time limit (which is 300 seconds / 5 minutes in Chrome).
If I send a request to a non-existing address or a server that is down there will be an error response, right?
My question is, what network or server condition will cause the request to hang until timed out, as opposed to quickly returning an error response?
Upvotes: 1
Views: 1101
Reputation: 4596
Generally, on the server side you have a thread pool or some event queue to handle incoming requests (lets call this the IO thread pool). The actual processing of the request happens on another thread (the main thread, if single threaded). Let's call this the processing thread pool. On the processing thread, the request is processed quickly and a response is returned to the IO thread thread. This is a simplified version of the request response anatomy.
---------- ----------------- ------------------ ---------------------
| client | <----> | load balancer | <---> | request thread | <---> | processing thread |
---------- ----------------- ------------------ ---------------------
When the client sends a request to the server, it get's accepted by the request thread pool and has to wait for until the server can process the incoming request. There may be a delay for a variety of reasons, like being blocked by a long running database query or performing expensive computations like 3D rendering etc. But more often than not, this happens because something is wrong like unclosed resources that are eating away from the processing thread pool.
Let's try an example, here is a simple server written in node using the express framework. In node there is just a single thread for processing, the main thread. Let's see what happens when that thread is blocked.
const express = require('express')
const app = express();
const port = 3000;
var sleep = function(seconds) {
var waitTill = new Date(new Date().getTime() + seconds * 1000);
while(waitTill > new Date()){}
};
app.get('/slow', (req, res) => {
// The sleep here signifies that process is taking a long time for whatever reason
sleep(1);
res.send('Slow query returns');
});
app.get('/fast', (req, res) => {
res.send('Fast query returns');
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
});
Let's build a simple client to do test the application.
var unirest = require('unirest');
var i = 0;
var j = [];
var tot = 20;
for (var i=0; i < tot; i++) {
j = j.concat(i);
}
j.forEach(function(i) {
console.time("No: " + i);
unirest('GET', 'http://localhost:3000/fast')
.end(function (res) {
if (res.error) throw new Error(res.error);
console.timeEnd("No: " + i);
});
});
j.forEach(function(i) {
console.time("No: " + (i+tot));
unirest('GET', 'http://localhost:3000/slow')
.end(function (res) {
if (res.error) throw new Error(res.error);
console.timeEnd("No: " + (i+tot));
});
});
Output from the client:
No: 0: 31.406ms
No: 1: 31.203ms
No: 3: 31.171ms
No: 2: 31.628ms
No: 4: 31.662ms
No: 5: 31.835ms
No: 7: 31.703ms
No: 6: 32.288ms
No: 8: 32.295ms
No: 9: 32.459ms
No: 10: 1027.011ms
No: 11: 2027.326ms
No: 12: 3027.625ms
No: 13: 4027.925ms
No: 15: 5027.833ms
No: 14: 6028.303ms
No: 16: 7028.411ms
No: 18: 8030.380ms
No: 17: 9030.837ms
No: 19: 10030.692ms
As you can see, the slow query takes time to run (a whole 10 seconds for the 10th request sent) and you can extrapolate this to as long as required.
The above list is not exhaustive by any means. Anything you think can go wrong probably will.
While the processing thread pool is busy catering to older requests, the request thread pool continues to accept new connections and stall them out until the server crashes. Hence your server can take abnormally long to respond. But this is universally a bad sign.
Upvotes: 2
Reputation: 5941
An XMLHttpRequest timeout ProgressEvent is dispatched if:
The author specified timeout has passed before the fetch completed.
So the network or server conditions which will cause the request to hang are basically any which result in a long time to return a response.
etc etc
If I send a request to a non-existing address or a server that is down there will be an error response, right?
The non existing address will probably return an error from your DNS server, so you should be good there. A server that is down won't do anything, it's down. What happens there is between your timeout setting and the redundancy of the server you are trying to access
Upvotes: 3
Reputation: 6747
There are many reasons why a request might time out. The simplest one being, that the connection is bad and it takes too long to get a response back.
I don't know what you are exactly looking for and why you need this information to begin with, but you get an error response quickly, if the URL you are trying to reach does not exist. For example if you try to request something from http://asdahgo8fgasidf.com/
(does not exist).
A valid use-case for requests that time out is long polling. This is when you are sending a request to a server, but it doesn't give an answer until it has one. For example while checking for new messages in a messenger app. If the request timed out, the client just sends a new one. This is to ensure that you get an update as soon as there is one available.
Upvotes: 1