Tarang
Tarang

Reputation: 75955

Add intentional latency in express

Im using express with node.js, and testing certain routes. I'm doing this tute at http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/

Im calling the http://localhost:3000/wines via ajax (the content doesn't matter). But I want to test latency. Can I do something like make express respond after 2 seconds? (I want to simulate the ajax loader and I'm running on localhost so my latency is pretty much nil)

Upvotes: 65

Views: 31886

Answers (9)

Locoder
Locoder

Reputation: 22

In my case I wanted a way to have the same processing time for all of my endpoints.

The solution I found is to override one of the Response methods :

/* MINIMUM DELAY */
const minDelay = 200; /* ms */
app.use((req, res, next) => {
    const tmp = res.json;
    const start = new Date().getTime();
    (res.json as any) = async (body: any) => {
        await new Promise((re) => setTimeout(re, minDelay - new Date().getTime() + start));
        tmp.apply(res, [body]);
    };
    next();
});

This way an attacker would not be able to differentiate failed login requests from OK requests just by looking at the response time :)

Upvotes: 0

Josep Vicent Ibanez
Josep Vicent Ibanez

Reputation: 1758

app.get('/fakeDelay', function(req,res){
    let ms = req.query.t;
    ms = (ms>5000 || isNaN(ms)) ? 1000 : parseInt(ms); 
    setTimeout((()=> res.status(200).send({delay:ms})), ms);
})

Then request the URL as: http://localhost/fakeDelay/?t=2000 (max 5000ms and default of 1000ms on this example)

Update: Using a Promise. The function 'sleep' can be used for delaying any Express response or other async function.

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

app.get('/fakeDelay', async (req, res) => {
  await sleep(500);
  res.send([])
})

Upvotes: 6

David Weldon
David Weldon

Reputation: 64332

Just call res.send inside of a setTimeout:

setTimeout((() => {
  res.send(items)
}), 2000)

Upvotes: 73

Diomidis Spinellis
Diomidis Spinellis

Reputation: 19365

You can use the express-delay package.

The code below will delay all incoming requests by one second.

const app = require('express')();
const delay = require('express-delay');
app.use(delay(1000));

The package also offers the possibility to introduce a random delay within specified boundaries, e.g. by calling delay(1000, 2000) for a delay between one and two seconds.

Upvotes: 1

Lu Tran
Lu Tran

Reputation: 401

just add a comment on top of the solution of @maggocnx : put this middleware early (before your route handler)

app.use(function(req,res,next){setTimeout(next,1000)});

Upvotes: 3

Playdome.io
Playdome.io

Reputation: 3225

To apply it globaly on all requests you can use the following code:

app.use( ( req, res, next ) => {
    setTimeout(next, Math.floor( ( Math.random() * 2000 ) + 100 ) );
});

Time values are:

Max = 2000 (sort of.... min value is added so in reality its 2100)

Min = 100

Upvotes: 11

barryels
barryels

Reputation: 143

You could also just write your own generic delay handler using a Promise or callback (using a q promise in this case):

pause.js:

var q = require('q');

function pause(time) {
    var deferred = q.defer();

    // if the supplied time value is not a number, 
    // set it to 0, 
    // else use supplied value
    time = isNaN(time) ? 0 : time;

    // Logging that this function has been called, 
    // just in case you forgot about a pause() you added somewhere, 
    // and you think your code is just running super-slow :)
    console.log('pause()-ing for ' + time + ' milliseconds');

    setTimeout(function () {
        deferred.resolve();
    }, time);

    return deferred.promise;
}

module.exports = pause;

then use it however you'd like:

server.js:

var pause = require('./pause');

router.get('/items', function (req, res) {
    var items = [];

    pause(2000)
        .then(function () {
            res.send(items)
        });

});

Upvotes: 1

maggocnx
maggocnx

Reputation: 1612

Use as middleware, for all your requests

  app.use(function(req,res,next){setTimeout(next,1000)});

Upvotes: 116

durad
durad

Reputation: 335

Try connect-pause module. It adds delay to all or only some routes in your app.

Upvotes: 6

Related Questions