2

I am trying to test some some examples from the book I'm reading, "Learning Node 2012". And my application for testing the server by doing 2000 requests is pausing. The tester pauses after 5 requests and sends another 5 after a certain interval. Why is it pausing? How can I fix this?

The server code:

var http = require('http');
var fs = require('fs');

// write out numbers
var counter = 0;
function writeNumbers(res)
{

        for (var i = 0; i < 100; i++)
        {
                counter++;
                res.write(counter.toString() + '\n');
        }
}

// create the http server
http.createServer( function(req, res) {
        var query = require('url').parse(req.url).query;
        var app = require('querystring').parse(query).file + ".txt";

        // content header
        res.writeHead(200, { 'Content-Type': 'text/plain' } );

        // write out numbers
        writeNumbers(res);
        // timer to open file and read contents
        setTimeout(function() {
                console.log('opening ' + app);
                // open and read in file contents
                fs.readFile(app, 'utf8', function(err, data) {
                        if (err)
                                res.write('Could not find or open file for reading\n');
                        else
                                res.write(data);
                        res.end();
                });
        }, 2000);
}).listen(3000);

console.log('Server is running on port 3000');

The spam test code:

var http = require('http');

// the url we want, plus the path and options we need
var options = {
        host: 'localhost',
        port: 3000,
        path: '/?file=secondary',
        method: 'GET'
};

var processPublicTimeline = function(response) {
        // finished? ok, write the data to a file
        console.log('finished request');
};

for (var i = 0; i < 2000; i++)
{
        // make the request, and then end it, to close the connection
        http.request(options, processPublicTimeline).end();
}
user1766555
  • 57
  • 1
  • 3
  • 11
  • 2
    Possible duplicate of http://stackoverflow.com/questions/12060869/why-is-node-js-only-processing-six-requests-at-a-time – tiguchi Jan 23 '14 at 22:33

1 Answers1

1

While this definitely does have some relation to Why is node.js only processing six requests at a time?

It is also because you are using a timeOut to call res.end() to close the connection/respond, and thus move onto the next connection in queue.

You should instead think about these types of things aynchronously, without the use of timeOuts, but instead with callBacks.

So your code for your two main blocks could be more like:

var counter = 0;
function writeNumbers(res, callBack){
    // notice callBack argument

    for (var i = 0; i < 100; i++){
        counter++;
        res.write(counter.toString() + '\n');
    }

    // execute callBack (if it exists)
    if(callBack && typeof callBack === "function") callBack();
}

http.createServer( function (req, res){
    var query = require('url').parse(req.url).query;
    var app = require('querystring').parse(query).file + ".txt";

    res.writeHead(200, { 'Content-Type': 'text/plain' } );

    writeNumbers(res, function(){

        // Notice this function which is passed as a callBack argument for writeNumbers to evaluate.
        // This executes when the main writeNumbers portion finishes.

        console.log('opening ' + app);

        fs.readFile(app, 'utf8', function(err, data) {
            if (err)
                res.write('Could not find or open file for reading\n');
            else
                res.write(data);
            res.end();
        });
    });

}).listen(3000);

Notice that your writeNumbers function now takes a callBack argument to execute when it is done, and that when you call it in your server's object, you pass a function as that callBack argument. This is one of the core patterns used very frequently in node.js/javascript applications.

This means that you aren't waiting for a timeOut to execute to end your request response, but rather it is ended as it processes your response, and moves onto the next connection immediately. This is likely to happen wayyyy quicker than 2 seconds (the amount of your timeOut). So you should see your connections being processed much quicker.

Because (as someone pointed out in your comments) your system is only able to handle a few open TCP connections at a time, you want to move through your connections as quickly as possible. Leveraging a callBack chain can help you do that when you want to do things in a certain order, or if you need to wait for certain processes to finish before executing others, without guessing with a timeOut.

Hope this helps!

Community
  • 1
  • 1
Arjun Mehta
  • 2,500
  • 1
  • 24
  • 40