Skip to content

Commit 8cded3a

Browse files
committed
fix: token bucket refill loses fractional interval progress
lastRefill was reset to `now` on each refill, discarding sub-interval elapsed time. Under concurrency this caused QPS to be lower than configured and irregular. Fix: advance lastRefill by whole intervals only so fractional progress accumulates correctly across refills.
1 parent 99257fc commit 8cded3a

1 file changed

Lines changed: 8 additions & 4 deletions

File tree

backend/src/services/benchmarkEngine.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,23 @@ class TokenBucket {
7474

7575
private refill(): void {
7676
const now = Date.now();
77-
const newTokens = (now - this.lastRefill) / this.intervalMs;
77+
const elapsed = now - this.lastRefill;
78+
const newTokens = elapsed / this.intervalMs;
7879
if (newTokens >= 1) {
79-
this.tokens = Math.min(1, this.tokens + newTokens);
80-
this.lastRefill = now;
80+
// Advance lastRefill by whole intervals only, preserving fractional progress
81+
const wholeIntervals = Math.floor(newTokens);
82+
this.lastRefill += wholeIntervals * this.intervalMs;
83+
this.tokens = Math.min(1, this.tokens + wholeIntervals);
8184
}
8285
}
8386

8487
tryAcquire(): number {
8588
this.refill();
8689
if (this.tokens >= 1) {
8790
this.tokens -= 1;
88-
return 0;
91+
return 0; // got a token immediately
8992
}
93+
// Time until next token is available
9094
return this.intervalMs - (Date.now() - this.lastRefill);
9195
}
9296
}

0 commit comments

Comments
 (0)