in packages/sdk/src/fetch-util.ts [179:212]
rateLimit(tokenFillRate: number, { maxTokens = tokenFillRate, initialTokens = tokenFillRate } = {}) {
precondition(tokenFillRate > 0, 'tokenFillRate must be positive');
let lastRefillTime = Number.NEGATIVE_INFINITY;
let tokens = initialTokens;
let nextRun = Promise.resolve();
return this.compose(next => request => {
nextRun = nextRun
// catch the potential abort of the previous run
.catch(() => {})
.then(async () => {
refillTokens();
// we can only send a request if we have at least one token
if (tokens < 1) {
// wait until tokens is one
await abortableSleep(((1 - tokens) / tokenFillRate) * 1000, request.signal);
}
});
return nextRun.then(() => {
tokens--;
return next(request);
});
});
function refillTokens() {
const currentTime = Date.now();
// initialTokens might be higher than maxTokens, so we don't refill until we've dropped below maxTokens
if (Number.isFinite(lastRefillTime) && tokens < maxTokens) {
const elapsed = (currentTime - lastRefillTime) / 1000;
tokens = Math.min(maxTokens, tokens + elapsed * tokenFillRate);
}
lastRefillTime = currentTime;
}
}