Async: mapLimit with n/sec limit

Created on 27 Oct 2016  ·  8Comments  ·  Source: caolan/async

Is possible to limit parallel execution to a number/sec?
This is necessary for those services, like Google Sheet API Limits and Quotas (see https://developers.google.com/analytics/devguides/config/mgmt/v3/limits-quotas) , that limit the number of queries per second (QPS) per IP.
Thanks!

docs feature wont fix

Most helpful comment

OP: maybe you've already solved this.....I've used another NPM package to implement rate limiting using leakybucket or token bucket models. https://www.npmjs.com/package/limiter This has worked well for me in the past. To create a rate limited mapper function, just do something like this. Your mapper function is directly used with async.

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

function rateLimitedMapper(item, callback)
{
  limiter.removeTokens(1, function(err, remainingRequests) {
    console.log("working on item: " + item);
    callback(null, item.length);
  });
}

async.map(input, rateLimitedMapper, function(err, results) {
  // do something with results
 });

All 8 comments

Similar features have been asked about before. ( #1113 #1082 #1020 #942 #37 ) There is demand for some sort of "throttled queue" functionality, but managing that kind of construct properly is a hard problem.

This is the kind of thing people use dedicated message queue libraries and systems for.

tl;dr you/async would need some sort of smoothing function to do this. If we were to do this we would probably implement an exponential smoothing function a token bucket.

If anyone is interested in working on this let us know :)

OP: maybe you've already solved this.....I've used another NPM package to implement rate limiting using leakybucket or token bucket models. https://www.npmjs.com/package/limiter This has worked well for me in the past. To create a rate limited mapper function, just do something like this. Your mapper function is directly used with async.

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

function rateLimitedMapper(item, callback)
{
  limiter.removeTokens(1, function(err, remainingRequests) {
    console.log("working on item: " + item);
    callback(null, item.length);
  });
}

async.map(input, rateLimitedMapper, function(err, results) {
  // do something with results
 });

That seems like a lib we should mention in our readme. Seems to do what we wanted to build.

Yep, it's using a token bucket under the hood which is the same approach I was taking. I'd be quite fine deferring rate limitting to external libraries :)

Yeah, honestly I wouldn't be thrilled with having to support something like that within Async. There are so many gotchas when doing rate limiting.

Changing the tags on this to signify that we need a place in the docs for other libraries that extend Async.

Was this page helpful?
0 / 5 - 0 ratings