Open stansv opened 5 years ago
Thank you for the ticket, was just looking to implement something like this. Currently trying to wrap Hubspot's API calls. Hubspot uses a window limit instead of a hard limit like stripe.
@stansv how about chaining the limiters?
const limiterPerDay = new Bottleneck({
reservoir: 5000,
reservoirRefreshAmount: 5000,
reservoirRefreshInterval: 24 * 60 * 60 * 1000, // must be divisible by 250
});
const limiterPerMinute = new Bottleneck({
reservoir: 60,
reservoirRefreshAmount: 60,
reservoirRefreshInterval: 60 * 1000, // must be divisible by 250
});
limiterPerMinute.chain(limiterPerDay);
limiterPerMinute.schedule(() => {...});
To handle out of limit errors you can use the following code:
limiterPerMinute.on('failed', (error, jobInfo) => {
const isOutOfLimits = ...;
if (isOutOfLimits) {
limiterPerMinute.incrementReservoir(-Infinity);
return 60 * 1000;
}
});
As far as I know the sliding window log technique gives the best accuracy having only one disadvantage in relatively high memory consumption, which is OK for API clients. We consume API with strict limits: 60 requests per one-minute window and 5000 per 24-hour window. Exceeding these limits is very undesirable since each new attempt will be counted by server and fail, extending the time we cannot use API.
Do you have any plans to support such functionality? Looks like this can be accomplished with ZREMRANGEBYSCORE (https://engineering.classdojo.com/blog/2015/02/06/rolling-rate-limiter/). There's also some NodeJS implementation referenced from this article but looks like it doesn't support delayed execution as like in your library.