jhurliman/node-rate-limiter

Add tokens or dynamically set number of tokens

Closed this issue · 2 comments

I am using limiter to throttle calls to a DynamoDB table. DynamoDB will return the Consumed Capacity, which sometimes is 0. I would like to NOT delay the next call if the Consumed Capacity is 0 but I don't see a straight forward way to do this. I have tried setting then number of tokens to 2, then running tryRemoveTokens(1) if Consumed Capacity is > 0. I also tried the opposite and this.limiter.tokensThisInterval+=1; if Consumed Capacity is 0. Neither seems to work the way I thought it would. tryRemoveTokens would run into if (count > this.tokenBucket.tokensPerInterval - this.tokensThisInterval) and return false.

I am probably misunderstanding how this works. Here is example code snippets.

limiter = new RateLimiter(2, 1000);
limiter.removeTokens(2, (err, remainingRequests) => {
   query.returnConsumedCapacity().exec((err, items) => {
        if (items.ConsumedCapacity > 0 || items.Count > 0) {
           limiter.tryRemoveTokens(1);
         }
    });
});
limiter = new RateLimiter(1, 1000);
limiter.removeTokens(1, (err, remainingRequests) => {
   query.returnConsumedCapacity().exec((err, items) => {
        if (items.ConsumedCapacity === 0 || items.Count === 0) {
            this.limiter.tokensThisInterval+=1;
         }
    });
});

When you get information back from an API about what the true capacity is at any given moment, I think the best option is to modify the number of tokens in the token bucket directly. Example:

this.limiter.tokenBucket.content = 2

This works fine for reducing the current number of tokens. The problem with adding more tokens is that any current pending calls to removeTokens will already have a timer scheduled and there is no support (yet) for canceling that timer and retrying. It would be possible to add a refreshPending() method but it's not something I have time to implement myself right now.