Search code examples
node.jshapi.js

Concurrent request to hapijs(v20) handler which returns promise


I have an API that was developed using the HapiJS framework. If a handler returns a promise then subsequent requests are waiting to complete the existing request. So basically I was doing an asynchronous process while hitting the API.

Please find the following example:

// Server Creation ...

// Route Creation
server.route({
    method: 'GET',
    path: '/v1/check',
    handler: () => {
        console.log('Check');

        return new Promise((resolve) => {
            setTimeout(() => {
                console.log('Check Response')
                resolve({check: 1});
            }, 1000);

        });
    }
});

While executing the same routes in 3 different tabs of the browser and reloading all at the same time.

Log:

Check
Check Response
Check
Check Response
Check
Check Response

Expected Log:

Check
Check
Check
Check Response
Check Response
Check Response
// Not expecting the same log, but wanted parallel execution.

So my doubt is if 100 users hitting the same API then the 100th request has to wait for the completion of 99 requests?

Was a bit confused with the output.


Solution

  • It's probably not ideal to test using the browser since they usually have a cap on how many concurrent connection they allow for.

    When I run your example using Apache Bench I get the expected result.

    Server:

    'use strict';
    
    const Hapi = require('@hapi/hapi');
    
    const init = async () => {
    
        const server = Hapi.server({
            port: 3000,
            host: 'localhost'
        });
    
        server.route({
            method: 'GET',
            path: '/v1/check',
            handler: () => {
                console.log('Check');
        
                return new Promise((resolve) => {
                    setTimeout(() => {
                        console.log('Check Response')
                        resolve({check: 1});
                    }, 1000);
        
                });
            }
        });
    
        await server.start();
        console.log('Server running on %s', server.info.uri);
    };
    
    init();
    

    Test:

     docker run -it --net="host" --rm -t devth/alpine-bench -n10 -c10 http://host.docker.internal:3000/v1/check
    

    Result:

    $ node index.js
    Server running on http://localhost:3000
    Check
    Check
    Check
    Check
    Check
    Check
    Check
    Check
    Check
    Check
    Check Response
    Check Response
    Check Response
    Check Response
    Check Response
    Check Response
    Check Response
    Check Response
    Check Response
    Check Response