Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

throttle requests in Node.js

I have an array. I can loop over it with the foreach method.

data.forEach(function (result, i) {

     url = data[i].url;

     request(url);

});

The request function is making a http request to the given url. However making all these requests at the same time leads to all sorts of problems.

So I thought I should slow things down by introducing some-sort of timer.

But I have no idea how will be able to combine a forach loop with setTimeOut/setInterval

Please note am doing this on the server (nodejs) rather on the browser.

Thanks for you help.

like image 333
saeed Avatar asked Sep 24 '12 19:09

saeed


People also ask

What is throttle in node js?

I use async-sema module handle throttle HTTP request. Which means it allow you send HTTP request with a rate limit. Here is an example: A simple Node. js server, add express-rate-limit middleware to API so that the API has rate-limit feature.

What are throttle requests?

Throttling is the process of limiting the number of requests you (or your authorized developer) can submit to a given operation in a given amount of time. A request can be when you submit an inventory feed or when you make an order report request.

How do I throttle API requests?

One way to implement API throttling in distributed systems is to use sticky sessions. In this method, all requests from a user are always serviced by a particular server. However, this solution is not well-balanced or fault tolerant. The second solution to API throttling in distributed systems are locks.

How do I limit API requests in node js?

Copy and paste the following code inside this file: // src/middlewares/rateLimiter. js import rateLimit from 'express-rate-limit'; export const rateLimiterUsingThirdParty = rateLimit({ windowMs: 24 * 60 * 60 * 1000, // 24 hrs in milliseconds max: 100, message: 'You have exceeded the 100 requests in 24 hrs limit!


2 Answers

As your problem is global, you should adjust your request function to have only 5 request running at a time - using a global, static counter. If your request was before something like

function request(url, callback) {
    ajax(url, callback);
}

now use something like

var count = 0;
var waiting = [];
function request(url, callback) {
    if (count < 5) {
        count++;
        ajax(url, function() {
            count--;
            if (waiting.length)
                request.apply(null, waiting.shift());
            callback.apply(this, arguments);
        });
    } else
        waiting.push(arguments);
}
like image 98
Bergi Avatar answered Sep 19 '22 11:09

Bergi


data.forEach(function (result, i) {

     url = data[i].url;

     setTimeout(
         function () {
              request(url);
         }, 
         1000 * (i + 1) // where they will each progressively wait 1 sec more each
     );

 });
like image 44
Mark Pieszak - Trilon.io Avatar answered Sep 18 '22 11:09

Mark Pieszak - Trilon.io