添加whatshub工单
This commit is contained in:
Executable
+82
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Browser 并发槽位限流器:standard / real 各自独立队列
|
||||
*/
|
||||
const { QUEUE_TIMEOUT_MS } = require('./constants');
|
||||
|
||||
class BrowserConcurrencyLimiter {
|
||||
/**
|
||||
* @param {number} max 最大并发 Browser 数
|
||||
*/
|
||||
constructor(max) {
|
||||
this.max = max;
|
||||
this.active = 0;
|
||||
this.waiters = [];
|
||||
}
|
||||
|
||||
/** @returns {{ max: number, active: number, queued: number }} */
|
||||
getStats() {
|
||||
return { max: this.max, active: this.active, queued: this.waiters.length };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} taskName
|
||||
* @param {number} [timeoutMs]
|
||||
*/
|
||||
async acquire(taskName, timeoutMs = QUEUE_TIMEOUT_MS) {
|
||||
if (this.active < this.max) {
|
||||
this.active++;
|
||||
console.log(`[并发槽位] ${taskName} 立即获取 (${this.active}/${this.max})`);
|
||||
return;
|
||||
}
|
||||
console.log(`[并发槽位] ${taskName} 排队等待 (队列 ${this.waiters.length + 1})`);
|
||||
await new Promise((resolve, reject) => {
|
||||
const entry = {
|
||||
resolve: () => {
|
||||
this.active++;
|
||||
console.log(`[并发槽位] ${taskName} 出队执行 (${this.active}/${this.max})`);
|
||||
resolve();
|
||||
},
|
||||
reject,
|
||||
};
|
||||
if (timeoutMs > 0) {
|
||||
entry.timer = setTimeout(() => {
|
||||
const idx = this.waiters.indexOf(entry);
|
||||
if (idx >= 0) {
|
||||
this.waiters.splice(idx, 1);
|
||||
reject(new Error('QUEUE_TIMEOUT'));
|
||||
}
|
||||
}, timeoutMs);
|
||||
}
|
||||
this.waiters.push(entry);
|
||||
});
|
||||
}
|
||||
|
||||
/** @param {string} taskName */
|
||||
release(taskName) {
|
||||
this.active = Math.max(0, this.active - 1);
|
||||
const next = this.waiters.shift();
|
||||
if (next) {
|
||||
if (next.timer) clearTimeout(next.timer);
|
||||
next.resolve();
|
||||
} else {
|
||||
console.log(`[并发槽位] ${taskName} 释放 (${this.active}/${this.max})`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {string} taskName
|
||||
* @param {() => Promise<T>} fn
|
||||
* @returns {Promise<T>}
|
||||
*/
|
||||
async run(taskName, fn) {
|
||||
await this.acquire(taskName);
|
||||
try {
|
||||
return await fn();
|
||||
} finally {
|
||||
this.release(taskName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { BrowserConcurrencyLimiter };
|
||||
Reference in New Issue
Block a user