jhurliman / node-rate-limiter

A generic rate limiter for node.js. Useful for API clients, web crawling, or other tasks that need to be throttled
MIT License
1.51k stars 135 forks source link

Will this work with what I need to do? #24

Closed sean-hill closed 9 years ago

sean-hill commented 9 years ago

Hey there

I have a list of 100k emails. I'd like to only send 25 per second. I have setup the code like this:

var async = require('async');
var RateLimiter = require('limiter').RateLimiter;
var limiter = new RateLimiter(25, 'second');

var emails = [];

for (var i = 0; i < 100000; i++) {
    emails.push(i);
};

async.eachSeries(emails, function(email, nextEmail){

    limiter.removeTokens(1, function(err, remainingRequests) {
        asyncEmailFunction(email);
        return nextEmail();
    });

});

// Just as an example
function asyncEmailFunction(email) {
    console.log(email);
};

It works great until about 300 emails, then it just bogs down and doesn't complete them as fast.

sean-hill commented 9 years ago

Haha. I don't even need this module. Here's my solution. 1000ms / 25 = 40ms.

async.eachSeries(emails, function(email, nextEmail){

    setTimeout(function(){
        asyncEmailFunction(email);
        return nextEmail();
    }, 40);

});
jhurliman commented 9 years ago

Glad you worked out a solution. This module is most useful for dealing with unexpected bursts of activity. When you have a known number of tasks that you want to run at a known rate there are easier options like what you pasted above.

andrewschreiber commented 7 years ago

For future reference, here is how you'd approach this with RateLimter (ES6):

import { RateLimiter } from "limiter";

const emails = [...]

const limiter = new RateLimiter(1, 40); // max 1 email per 40 ms

emails.forEach(email  => {
    limiter.removeTokens(1, () => {
        this.sendEmail(email);
    });
});