2024-11-15 23:51:18 +08:00
|
|
|
export class LockoutTimer {
|
|
|
|
// A very simple, quick, inexact lockout timer
|
|
|
|
// For each request isLocked() or updateBucketTime() must be called before addCount()
|
|
|
|
// counts in buckets of countPeriodMs
|
|
|
|
// each period starts with an empty bucket
|
|
|
|
// suggest SB_LOCKOUT_TIME_MS=60000 SB_LOCKOUT_LIMIT=10
|
|
|
|
bucketTime: number = 0;
|
|
|
|
bucketCount: number = 0;
|
|
|
|
bucketSize: number;
|
|
|
|
limit: number;
|
|
|
|
disabled: boolean;
|
|
|
|
|
|
|
|
constructor(
|
2024-11-15 23:50:50 +08:00
|
|
|
countPeriodMs: number,
|
|
|
|
limit: number,
|
2024-11-15 23:51:18 +08:00
|
|
|
) {
|
|
|
|
this.disabled = isNaN(countPeriodMs) || isNaN(limit) || countPeriodMs < 1 ||
|
|
|
|
limit < 1;
|
|
|
|
this.bucketSize = countPeriodMs;
|
|
|
|
this.limit = limit;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateBucketTime(): void {
|
|
|
|
const currentBucketTime = Math.floor(Date.now() / this.bucketSize);
|
|
|
|
if (this.bucketTime === currentBucketTime) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// the bucket is too old - empty it
|
|
|
|
this.bucketTime = currentBucketTime;
|
|
|
|
this.bucketCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
isLocked(): boolean {
|
|
|
|
if (this.disabled) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
this.updateBucketTime();
|
|
|
|
return this.bucketCount >= this.limit;
|
|
|
|
}
|
|
|
|
|
|
|
|
addCount(): void {
|
|
|
|
// isLocked or updateBucketTime must be called first to keep bucketTime current
|
|
|
|
this.bucketCount++;
|
|
|
|
}
|
|
|
|
}
|