optimize polling strategy

This commit is contained in:
被遗忘的记忆
2025-02-18 12:51:01 +08:00
committed by GitHub
parent 531148733b
commit 0212c88190
+81 -37
View File
@@ -70,6 +70,10 @@ class SessionManager {
// 记录请求次数 // 记录请求次数
session.youTotalRequests = 0; session.youTotalRequests = 0;
// 权重
if (typeof session.weight !== 'number') {
session.weight = 1;
}
} }
} }
@@ -224,7 +228,7 @@ class SessionManager {
return browserInstance; return browserInstance;
} }
} }
throw new Error('当前负载已饱和,请稍后再试'); throw new Error('当前负载已饱和,请稍后再试(以达到最大并发)');
}); });
} }
@@ -240,46 +244,80 @@ class SessionManager {
async getAvailableSessions() { async getAvailableSessions() {
const allSessionsLocked = this.usernameList.every(username => this.sessions[username].locked); const allSessionsLocked = this.usernameList.every(username => this.sessions[username].locked);
if (allSessionsLocked) { if (allSessionsLocked) {
throw new Error('所有会话处于饱和状态,请稍后再试'); throw new Error('所有会话处于饱和状态,请稍后再试(无可用账号)');
} }
// 轮询 // 收集所有valid && !locked && (不在冷却期)
const totalSessions = this.usernameList.length; let candidates = [];
for (let i = 0; i < totalSessions; i++) { for (const username of this.usernameList) {
const index = (this.currentIndex + i) % totalSessions;
const username = this.usernameList[index];
const session = this.sessions[username]; const session = this.sessions[username];
// 如果没被锁 并且 session.valid // 如果没被锁 并且 session.valid
if (session.valid && !session.locked) { if (session.valid && !session.locked) {
if (this.provider.enableRequestLimit && this.isInCooldown(username)) { if (this.provider.enableRequestLimit && this.isInCooldown(username)) {
// console.log(`账号 ${username} 处于 24 小时冷却中,跳过`); // console.log(`账号 ${username} 处于 24 小时冷却中,跳过`);
continue; continue;
} }
candidates.push(username);
}
}
const result = await session.mutex.runExclusive(async () => { if (candidates.length === 0) {
// 再次检查锁定状态 throw new Error('没有可用的会话');
if (session.locked) { }
// 随机洗牌
shuffleArray(candidates);
// 加权抽签
let weightSum = 0;
for (const uname of candidates) {
weightSum += this.sessions[uname].weight;
}
// 生成随机
const randValue = Math.floor(Math.random() * weightSum) + 1;
// 遍历并扣减
let cumulative = 0;
let selectedUsername = null;
for (const uname of candidates) {
cumulative += this.sessions[uname].weight;
if (randValue <= cumulative) {
selectedUsername = uname;
break;
}
}
if (!selectedUsername) {
selectedUsername = candidates[0];
}
const selectedSession = this.sessions[selectedUsername];
// 再尝试锁定账号
const result = await selectedSession.mutex.runExclusive(async () => {
if (selectedSession.locked) {
return null; return null;
} }
// 检查模式状态
if (session.modeStatus && session.modeStatus[session.currentMode]) {
session.locked = true;
session.requestCount++;
this.currentIndex = (index + 1) % totalSessions;
// 获取可用浏览器实例 // 判断是否可用
if (selectedSession.modeStatus && selectedSession.modeStatus[selectedSession.currentMode]) {
// 锁定
selectedSession.locked = true;
selectedSession.requestCount++;
// 获取可用浏览器
const browserInstance = await this.getAvailableBrowser(); const browserInstance = await this.getAvailableBrowser();
// 启动计时器 // 启动自动解锁计时器
if (SESSION_LOCK_TIMEOUT > 0) { if (SESSION_LOCK_TIMEOUT > 0) {
this.startAutoUnlockTimer(username, browserInstance.id); this.startAutoUnlockTimer(selectedUsername, browserInstance.id);
} }
return { return {
selectedUsername: username, selectedUsername,
modeSwitched: false, modeSwitched: false,
browserInstance: browserInstance browserInstance
}; };
} else if ( } else if (
this.isCustomModeEnabled && this.isCustomModeEnabled &&
@@ -287,40 +325,36 @@ class SessionManager {
this.provider && this.provider &&
typeof this.provider.switchMode === 'function' typeof this.provider.switchMode === 'function'
) { ) {
console.warn(`尝试为账号 ${username} 切换模式...`); console.warn(`尝试为账号 ${selectedUsername} 切换模式...`);
this.provider.switchMode(session); this.provider.switchMode(selectedSession);
session.rotationEnabled = false; selectedSession.rotationEnabled = false;
if (session.modeStatus && session.modeStatus[session.currentMode]) { if (selectedSession.modeStatus && selectedSession.modeStatus[selectedSession.currentMode]) {
session.locked = true; selectedSession.locked = true;
session.requestCount++; selectedSession.requestCount++;
this.currentIndex = (index + 1) % totalSessions;
// 获取可用浏览器实例
const browserInstance = await this.getAvailableBrowser(); const browserInstance = await this.getAvailableBrowser();
if (SESSION_LOCK_TIMEOUT > 0) { if (SESSION_LOCK_TIMEOUT > 0) {
this.startAutoUnlockTimer(username, browserInstance.id); this.startAutoUnlockTimer(selectedUsername, browserInstance.id);
} }
return { return {
selectedUsername: username, selectedUsername,
modeSwitched: true, modeSwitched: true,
browserInstance: browserInstance browserInstance
}; };
} }
} }
return null; return null;
}); });
if (result) { if (result) {
// 成功锁定会话,返回
return result; return result;
} else {
throw new Error('会话刚被占用或模式不可用!');
} }
} }
}
throw new Error('没有可用的会话');
}
startAutoUnlockTimer(username, browserId) { startAutoUnlockTimer(username, browserId) {
// 清除可能残留计时器 // 清除可能残留计时器
@@ -376,4 +410,14 @@ class SessionManager {
} }
} }
/**
* FisherYates 洗牌
*/
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
export default SessionManager; export default SessionManager;