Saturday, 27 January 2018

Node.js - Slow and chunky webservice (deliberately slow)

So I want to test event handling of a library available for VBA developers but to test it I need to first build a web server that is deliberately slow and chunky. I blogged a simple web service previously that chunked a request (taking each chunk to process a portion of the post body). This time I want to chunk the response.

We use setTimeout (just like a browser) to schedule execution of a block of code. We are not reading a file or anything we are simply sending text strings back. We are splitting this out into schedule chunks to fit nicely with Node.js asynchronous non-blocking interleaved execution pattern.

The node.js libraries used are http and url. http handles the request and response streams. url will parse the url including querystring which is required here, we parse out chunkCount from the querystring (and take 1 on default). Parsing the url make its easy to route the url, in the code we are only interested in urls that start with /slowAndChunkyWebService.

Use Visual Studio 2017 community with Node,js installed and create a console app then paste in the following code, then press F5 to start running.

'use strict';

const http = require('http');
const url = require('url');
const port = 34957;

console.log('Slow and chunky web servicen');

const requestHandler = (request, response) => {

    var url_parts = url.parse(request.url, true);
    var query = url_parts.query;

    if (url_parts.pathname == '/slowAndChunkyWebService') {

        var chunkCount = 0;

        try {
            chunkCount = parseInt(query.chunkCount);

            if (typeof (chunkCount) == "undefined") { chunkCount = 1; }

        }
        catch (ex) { chunkCount = 1; }

        console.log('main code about to call myWriteChunk() with chunkCount' + chunkCount + 'n');
        myWriteChunk(response, chunkCount);

    } else {
        console.log(request.url);
        response.end(request.url);
    }
}

function myWriteChunk(response, chunkCount) {
    console.log('myWriteChunk called chunkCount' + chunkCount + 'n')

    var chunky = "foobar".repeat(10);

    response.write(chunky);

    chunkCount--;

    if (chunkCount > 0) {
        setTimeout(function () { myWriteChunk(response, chunkCount) }, 1000)
    } else {
        console.log('about to schedule myResponseEndn')
        setTimeout(function () { myResponseEnd(response) }, 1000)
        
    }
}

function myResponseEnd(response) {
    console.log('myResponseEnd calledn')
    response.end();
}



const server = http.createServer(requestHandler);

server.listen(port, (err) => {
    if (err) {
        return console.log('something bad happened', err);
    }

    console.log(`server is listening on ${port}`);
})

One can test this by going to a browser and typing in the url...

http://localhost:34957/slowAndChunkyWebService?chunkCount=2

In the node.js console the following output should be seen...

Debugger listening on ws://127.0.0.1:48449/40a2b131-8546-4801-adf3-c3b16d0b72a2
For help see https://nodejs.org/en/docs/inspector
Debugger attached.
(node:17292) [DEP0062] DeprecationWarning: `node --inspect --debug-brk` is deprecated. Please use `node --inspect-brk` instead.
Slow and chunky web service

server is listening on 34957
main code about to call myWriteChunk() with chunkCount2

myWriteChunk called chunkCount2

myWriteChunk called chunkCount1

about to schedule myResponseEnd

myResponseEnd called

/favicon.ico

And the browser will show contents only after all of them have been received.

foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobar

No comments:

Post a Comment