Files
dependabot[bot] a84b41faa3 chore(deps-dev): bump eslint-plugin-unicorn from 74.0.0 to 75.0.0 (#23338)
* chore(deps-dev): bump eslint-plugin-unicorn from 74.0.0 to 75.0.0

Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 74.0.0 to 75.0.0.
- [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases)
- [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v74.0.0...v75.0.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-unicorn
  dependency-version: 75.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* style: fix unicorn-js/prefer-combined-guards

* style: fix prefer-smaller-scope

* style: fix prefer-continue

* style: fix prefer-early-return

* style: fix prefer-iterator-helpers

* style: add v75 recommended preset

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tony <TonyRL@users.noreply.github.com>
2026-09-22 07:08:43 +08:00

149 lines
4.2 KiB
TypeScript

import type { Config } from '@/config';
import logger from '@/utils/logger';
import unifyProxy from './unify-proxy';
export interface ProxyState {
uri: string;
isActive: boolean;
failureCount: number;
lastFailureTime?: number;
agent?: any;
dispatcher?: any;
urlHandler?: URL | null;
}
export interface MultiProxyResult {
currentProxy?: ProxyState | null;
allProxies: ProxyState[];
proxyObj: Config['proxy'];
getNextProxy: () => ProxyState | null;
markProxyFailed: (proxyUri: string) => void;
resetProxy: (proxyUri: string) => void;
}
const createMultiProxy = (proxyUris: string[], proxyObj: Config['proxy']): MultiProxyResult => {
const proxies: ProxyState[] = [];
let currentProxyIndex = 0;
for (const uri of proxyUris) {
const unifiedProxy = unifyProxy(uri, proxyObj);
if (unifiedProxy.proxyUri) {
proxies.push({
uri: unifiedProxy.proxyUri,
isActive: true,
failureCount: 0,
urlHandler: unifiedProxy.proxyUrlHandler,
});
}
}
if (proxies.length === 0) {
logger.warn('No valid proxies found in the provided list');
return {
allProxies: [],
proxyObj: proxyObj || {},
getNextProxy: () => null,
markProxyFailed: () => {},
resetProxy: () => {},
};
}
const healthCheckInterval = proxyObj?.healthCheckInterval || 60000;
const maxFailures = 3;
const healthCheck = () => {
const now = Date.now();
for (const proxy of proxies) {
if (!(!proxy.isActive && proxy.lastFailureTime && now - proxy.lastFailureTime > healthCheckInterval)) {
continue;
}
proxy.isActive = true;
proxy.failureCount = 0;
delete proxy.lastFailureTime;
logger.info(`Proxy ${proxy.uri} marked as active again after health check`);
}
};
setInterval(healthCheck, healthCheckInterval);
const getNextProxy = (): ProxyState | null => {
const activeProxies = proxies.filter((p) => p.isActive);
if (activeProxies.length === 0) {
logger.warn('No active proxies available');
return null;
}
let nextProxy = activeProxies[currentProxyIndex % activeProxies.length];
let attempts = 0;
while (!nextProxy.isActive && attempts < activeProxies.length) {
currentProxyIndex = (currentProxyIndex + 1) % activeProxies.length;
nextProxy = activeProxies[currentProxyIndex];
attempts++;
}
if (!nextProxy.isActive) {
return null;
}
return nextProxy;
};
const markProxyFailed = (proxyUri: string) => {
const proxy = proxies.find((p) => p.uri === proxyUri);
if (!proxy) {
return;
}
proxy.failureCount++;
proxy.lastFailureTime = Date.now();
if (proxy.failureCount >= maxFailures) {
proxy.isActive = false;
logger.warn(`Proxy ${proxyUri} marked as inactive after ${maxFailures} failures`);
} else {
logger.warn(`Proxy ${proxyUri} failed (${proxy.failureCount}/${maxFailures})`);
}
const activeProxies = proxies.filter((p) => p.isActive);
if (activeProxies.length === 0) {
return;
}
currentProxyIndex = (currentProxyIndex + 1) % activeProxies.length;
const nextProxy = getNextProxy();
if (nextProxy) {
logger.info(`Switching to proxy: ${nextProxy.uri}`);
}
};
const resetProxy = (proxyUri: string) => {
const proxy = proxies.find((p) => p.uri === proxyUri);
if (!proxy) {
return;
}
proxy.isActive = true;
proxy.failureCount = 0;
delete proxy.lastFailureTime;
logger.info(`Proxy ${proxyUri} manually reset`);
};
const currentProxy = getNextProxy();
if (currentProxy) {
logger.info(`Initial proxy selected: ${currentProxy.uri}`);
}
return {
currentProxy,
allProxies: proxies,
proxyObj: proxyObj || {},
getNextProxy,
markProxyFailed,
resetProxy,
};
};
export default createMultiProxy;