why settimeout blocks eventloop - node.js

Note: this is not a replicated post for those about settimeout, the key answer here is browser design options.
I am starting study node.js:
A simple example to test async:
var http=require('http');
http.createServer(
function(request, response){
response.writeHead(200);
response.write("Hello, dog is running");
setTimeout(
function(){
response.write("Dog is done");
response.end();
},
10000
);
}
).listen(8080);
console.log("Listen on port 8080")
One interesting thing is its behavior is differernt when in command lind with curl and in browser:
In Ubuntu 12.10, I use curl localhost:8080 in two consoles, they response in almost same 10 sends.
However, I open two browsers, make the request at almost same time, but the whole procedure took me 20 seconds?
thanks.

It's the browser waiting, not node.js
If you run the server and request http://localhost:8080/ in two tabs it takes 20 seconds because the browser waits for the first request to the same url before starting the second.
If you run the server and request http://localhost:8080/1 and http://localhost:8080/2 in two tabs it takes 10 seconds again.

Related

what does nodeJS express timeout actually do?

I was recently refactoring some code and came across this piece of code in server.js.
I looked out for the docs and I still have some unanswered questions.
const server = app.listen(port, function () {
console.log('Server started on port ' + port);
});
server.timeout = 600000 // 6 mins.
What is server.timeout actually doing above? If the response has to time out in 6 minutes, how is my download API still working? Each download takes more than 10 minutes to download. Also, I send a response back to the client after download is complete.
From the express docs:
The app.listen() method returns an http.Server object
From the Node.js docs:
The number of milliseconds of inactivity before a socket is presumed to have timed out.
emphasis added
This means that if there's an actively streaming download, this property will not apply. It only applies to sockets where ACKs are not received by the client for 6 minutes.

node http requests not executed concurrently if made from same browser

var http = require('http');
http.createServer(function (req, res) {
setTimeout(function () {
res.write("hello");
res.end();
}, 10000);
}).listen(8080);
this is my simple node server running on localhost.
Now if i hit this url localhost:8080 from two different browsers simultaneously, i get response at same time on both browsers i.e after around 10 secs.But on other hand when i do so from two different tabs of chrome browser, it takes 10 secs for one tab and another 10 secs for 2nd tab.
Seems like requests are being processed one after another rather than simultaneously.
can somebody explain?
It's a know browser issue, only happens when you make two requests in the same browser (or browser profile) and separate tabs (XHR requests can actually be done simultaneously).
Sources:
Chrome stalls when making multiple requests to same resource?
Multiple instances of PHP script won't load concurrently in the same browser from the same URL

Why is my Node express .post being called multiple times, and my res.send() never resolves the $http request?

My request look this -
$http.post('/api/internal/Properties/' + options.property.id + '/Upload', { Buildings: Buildings })
.success(function (data){
on the server side, this request can take a long time to process. Up to 5 minutes. Before it can finish (res.send()), the $http.post request is being called again, every few minutes.
When it finally does finish processing, the res.send(data) is never caught on the client side. It's like it just disappears.
Anything would help.
Thanks,
Each browser has it's own http request timeout.
So it will not wait for 5 minutes to complete request it would just fail.
Browser Timeouts .
In chrome it's 30 or 60 seconds.
In your case i suggest use sockets or something like that to show user what's up with uploading.
Hope this helps.

Node JS, delayed response

var http = require('http');
var s = http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello\n');
setInterval(function() {
res.end(' World\n');
},2000);
console.log("Hello");
});
s.listen(8080);
After starting the above server, i run,
curl http://127.0.0.1:8080
I get the required delay. output:
Hello <2 seconds> World
But in the browser the whole content loads after 2 seconds.
Hell World <together after 2s>
What am i doing wrong ?
The following piece of code opens up a response stream with the client and streams it to the client. So, in curl you'll get "Hello" first and "World" after 2 seconds (since you've set a timer of 2000 milliseconds).
res.write('Hello\n');
setTimeout(function() {
res.end(' World\n');
},2000);
But the browser renders it only after the complete response stream is recieved.
That is why you're getting the response after 2 seconds.
It is completely the browser's behavior. It doesn't utilize the response stream until the whole response is received. Once the stream is closed, the whole response will be ready to be utilized. However, in PHP there's a way to flush the response stream if need be.
However, if you're looking for streaming data on a frequent basis, this wouldn't be the best way to do it. I'd rather suggest you to use Comet technique or websockets.
I hope this is what you are looking for.
// simulate delay response
app.use((req, res, next) => {
setTimeout(() => next(), 2000);
});
browser behavior is different from curl. browser will not render the page, until you call res.end(). so if you want to load a part of a web page after a delay, you need to load that second part separately via a websocket or an ajax request. I recommend using websocets. take a look at socket.io, it's a simple way of using websockets in node.js.

node.js runs concurrently, or does it?

Boys and girls,
i've been messing around with node.js today and I can't seem to reproduce this concurrent magic.
i wrote this rather small server:
var http = require("http");
var server = http.createServer(function(req, res) {
setTimeout(function() {
res.writeHead(200,{"content-type":"text/plain"});
res.end("Hello world!");
}, 10000);
});
server.listen(8000);
but what's strange, when running localhost:8000 in multiple chrome tabs at the same time. its as if the request is 'queued'. 1st tab takes 10 seconds, 2nd tab takes 20 seconds, 3rd tab takes 30 seconds etc...
But when running this very example with Links it behaves how I expect it (concurrently handling requests).
P.S. This seems to occur in Chrome and Firefox
bizarre
The requests for the same URL/hostname get queued client-side in the browser. That has nothing to do with node.js, your code is fine.
If you use different URLs in each tab, you example should work. (for a few tabs)
Also have a look at: Multiple Ajax requests for same URL

Resources