mirror of
https://github.com/hcengineering/platform.git
synced 2025-02-06 19:11:01 +00:00
149d8cda46
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
44 lines
1.1 KiB
TypeScript
44 lines
1.1 KiB
TypeScript
/**
|
|
* @public
|
|
*/
|
|
|
|
export class RateLimitter {
|
|
idCounter: number = 0
|
|
processingQueue = new Map<string, Promise<void>>()
|
|
last: number = 0
|
|
|
|
queue: (() => Promise<void>)[] = []
|
|
|
|
constructor (readonly config: () => { rate: number, perSecond?: number }) {}
|
|
|
|
async exec<T, B extends Record<string, any> = {}>(op: (args?: B) => Promise<T>, args?: B): Promise<T> {
|
|
const processingId = `${this.idCounter++}`
|
|
const cfg = this.config()
|
|
|
|
if (this.processingQueue.size > cfg.rate) {
|
|
await Promise.race(this.processingQueue.values())
|
|
}
|
|
try {
|
|
const p = op(args)
|
|
this.processingQueue.set(processingId, p as Promise<void>)
|
|
return await p
|
|
} finally {
|
|
this.processingQueue.delete(processingId)
|
|
}
|
|
}
|
|
|
|
async add<T, B extends Record<string, any> = {}>(op: (args?: B) => Promise<T>, args?: B): Promise<void> {
|
|
const cfg = this.config()
|
|
|
|
if (this.processingQueue.size < cfg.rate) {
|
|
void this.exec(op, args)
|
|
} else {
|
|
await this.exec(op, args)
|
|
}
|
|
}
|
|
|
|
async waitProcessing (): Promise<void> {
|
|
await await Promise.race(this.processingQueue.values())
|
|
}
|
|
}
|