& so it begins
This commit is contained in:
40
packages/logic/core/rate.limiter.ts
Normal file
40
packages/logic/core/rate.limiter.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { logger } from "@pkg/logger";
|
||||
|
||||
export class RateLimiter {
|
||||
private requestTimestamps: number[] = [];
|
||||
private readonly callsPerMinute: number;
|
||||
|
||||
constructor(callsPerMinute: number = 60) {
|
||||
this.callsPerMinute = Math.min(callsPerMinute, 60);
|
||||
}
|
||||
|
||||
async checkRateLimit(): Promise<void> {
|
||||
const currentTime = Date.now();
|
||||
const oneMinuteAgo = currentTime - 60000; // 60 seconds in milliseconds
|
||||
|
||||
// Remove timestamps older than 1 minute
|
||||
this.requestTimestamps = this.requestTimestamps.filter(
|
||||
(timestamp) => timestamp > oneMinuteAgo,
|
||||
);
|
||||
|
||||
// If we're approaching the limit, wait until we have capacity
|
||||
if (this.requestTimestamps.length >= this.callsPerMinute) {
|
||||
const oldestRequest = this.requestTimestamps[0];
|
||||
const waitTime = oldestRequest + 60000 - currentTime;
|
||||
|
||||
if (waitTime > 0) {
|
||||
logger.warn(
|
||||
`Rate limit approaching (${this.requestTimestamps.length} requests in last minute). Sleeping for ${waitTime}ms`,
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
||||
// After waiting, some timestamps may have expired
|
||||
this.requestTimestamps = this.requestTimestamps.filter(
|
||||
(timestamp) => timestamp > Date.now() - 60000,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Add current request to timestamps
|
||||
this.requestTimestamps.push(Date.now());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user