@juzi/wechaty-puppet-whatsapp
Version:
Wechaty Puppet for WhatsApp
85 lines • 3.13 kB
JavaScript
import { EventEmitter } from 'events';
import { log } from '../config.js';
import { WA_ERROR_TYPE } from '../exception/error-type.js';
import WAError from '../exception/whatsapp-error.js';
import { sleep } from '../helper/miscellaneous.js';
const MAX_QUEUE_SIZE = 5000;
export class RateManager extends EventEmitter {
counter = 0;
emit(event, ...args) {
return super.emit(event, ...args);
}
on(event, listener) {
super.on(event, listener);
return this;
}
functionQueueMap = {};
runningMap = {};
getQueueLength(queueId) {
if (!this.functionQueueMap[queueId]) {
return 0;
}
return this.functionQueueMap[queueId].length;
}
async exec(func, options = {}) {
const queueId = options.queueId || 'default';
const { delayAfter, delayBefore, uniqueKey } = options;
if (!this.functionQueueMap[queueId]) {
this.functionQueueMap[queueId] = [];
}
if (this.functionQueueMap[queueId].length > MAX_QUEUE_SIZE) {
if (this.counter % MAX_QUEUE_SIZE === 0) {
log.error(`EXCEED_QUEUE_SIZE: Max queue size for id: ${queueId} reached: ${this.functionQueueMap[queueId].length} > ${MAX_QUEUE_SIZE}(max queue size). Drop these tasks.`);
this.counter = 0;
}
this.counter++;
}
return new Promise((resolve, reject) => {
this.functionQueueMap[queueId].push({ delayAfter, delayBefore, func, reject, resolve, uniqueKey });
if (!this.runningMap[queueId]) {
this.runningMap[queueId] = true;
void this.execNext(queueId);
}
});
}
async execNext(queueId) {
const queue = this.functionQueueMap[queueId];
if (!queue) {
return;
}
const funcObj = queue.shift();
if (!funcObj) {
throw WAError(WA_ERROR_TYPE.ERR_RATE_FUNCTION_NOT_FOUND, `can not get funcObj from queue with id: ${queueId}.`);
}
const { delayAfter, delayBefore, func, resolve, reject, uniqueKey } = funcObj;
await sleep(delayBefore);
try {
const result = await func();
resolve(result);
/**
* If uniqueKey is given, will resolve functions with same key in the queue
*/
if (uniqueKey) {
const sameFuncIndexes = queue.map((f, index) => ({ func: f, index }))
.filter(o => o.func.uniqueKey === uniqueKey)
.map(o => o.index)
.sort((a, b) => b - a);
for (const index of sameFuncIndexes) {
const [sameFunc] = queue.splice(index, 1);
sameFunc.resolve(result);
}
}
}
catch (e) {
reject(e);
}
await sleep(delayAfter);
if (queue.length > 0) {
await this.execNext(queueId);
}
else {
delete this.runningMap[queueId];
}
}
}
//# sourceMappingURL=rate-manager.js.map