I have 1000 records that need to hit an API endpoint that is rate limited. I want to make it so that there is only 5 calls on the URL at any given time so that I am not making 1
To limit the number of concurrent requests that are in-flight at once, I'd recommend using Bluebird's Promise.map() which offers a concurrency option. It will do all of the following for you:
Here's how you would use it:
const Promise = require('bluebird');
Promise.map(records, r => {
let placeName = r['Place Name'];
return geocoder.geocodeAsync(placeName));
}, {concurrency: 5}).then(results => {
// all results here
}).catch(err => {
// process error here
});
Note: Rate limiting is not usually strictly the same as number of concurrent requests. Limiting the number of concurrent requests will make it more likely that you stay under a rate limit, but won't guarantee it. There are specific rate limiting modules that can manage to a rate limit more directly.
You can add a delay to each request using Bluebird's .delay().
const Promise = require('bluebird');
Promise.map(records, r => {
let placeName = r['Place Name'];
return geocoder.geocodeAsync(placeName)).delay(500);
}, {concurrency: 5}).then(results => {
// all results here
}).catch(err => {
// process error here
});
A classic algorithm for dealing with some types of rate limits is called the leaky bucket algorithm.
If your limit is 50 requests/sec, then you can just make sure that your concurrency number times your delay value never allows more than 50/sec.