refactor(provider-pool): 优化提供商池配置管理和健康检查逻辑
- 移除未使用的提供商池配置输入监听器 - 默认启用提供商池配置文件路径配置 - 修改健康检查方法参数名以更清晰表达意图 - 仅在明确要求时重置提供商使用计数 - 调整文件扫描深度以支持嵌套凭证目录结构 - 重载配置时更新提供商池管理器状态
This commit is contained in:
parent
1c22b8c5c9
commit
9c114e2a7d
5 changed files with 37 additions and 18 deletions
|
|
@ -270,9 +270,9 @@ export async function initializeConfig(args = process.argv.slice(2), configFileP
|
|||
currentConfig.SYSTEM_PROMPT_CONTENT = await getSystemPromptFileContent(currentConfig.SYSTEM_PROMPT_FILE_PATH);
|
||||
|
||||
// 加载号池配置
|
||||
// if (!currentConfig.PROVIDER_POOLS_FILE_PATH) {
|
||||
// currentConfig.PROVIDER_POOLS_FILE_PATH = 'provider_pools.json';
|
||||
// }
|
||||
if (!currentConfig.PROVIDER_POOLS_FILE_PATH) {
|
||||
currentConfig.PROVIDER_POOLS_FILE_PATH = 'provider_pools.json';
|
||||
}
|
||||
if (currentConfig.PROVIDER_POOLS_FILE_PATH) {
|
||||
try {
|
||||
const poolsData = await pfs.readFile(currentConfig.PROVIDER_POOLS_FILE_PATH, 'utf8');
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ export class ProviderPoolManager {
|
|||
* @param {object} providerConfig - The configuration of the provider to mark.
|
||||
* @param {boolean} isInit - Whether to reset usage count (optional, default: false).
|
||||
*/
|
||||
markProviderHealthy(providerType, providerConfig, isInit = false) {
|
||||
markProviderHealthy(providerType, providerConfig, resetUsageCount = false) {
|
||||
if (!providerConfig?.uuid) {
|
||||
this._log('error', 'Invalid providerConfig in markProviderHealthy');
|
||||
return;
|
||||
|
|
@ -177,10 +177,11 @@ export class ProviderPoolManager {
|
|||
provider.config.isHealthy = true;
|
||||
provider.config.errorCount = 0;
|
||||
provider.config.lastErrorTime = null;
|
||||
if (isInit) {
|
||||
// 只有在明确要求重置使用计数时才重置
|
||||
if (resetUsageCount) {
|
||||
provider.config.usageCount = 0;
|
||||
}
|
||||
this._log('info', `Marked provider as healthy: ${provider.config.uuid} for type ${providerType}`);
|
||||
this._log('info', `Marked provider as healthy: ${provider.config.uuid} for type ${providerType}${resetUsageCount ? ' (usage count reset)' : ''}`);
|
||||
|
||||
this._debouncedSave(providerType);
|
||||
}
|
||||
|
|
@ -277,11 +278,13 @@ export class ProviderPoolManager {
|
|||
if (isHealthy) {
|
||||
if (!providerStatus.config.isHealthy) {
|
||||
// Provider was unhealthy but is now healthy
|
||||
this.markProviderHealthy(providerType, providerConfig, isInit);
|
||||
// 恢复健康时不重置使用计数,保持原有值
|
||||
this.markProviderHealthy(providerType, providerConfig);
|
||||
this._log('info', `Health check for ${providerConfig.uuid} (${providerType}): Marked Healthy (actual check)`);
|
||||
} else {
|
||||
// Provider was already healthy and still is
|
||||
this.markProviderHealthy(providerType, providerConfig, isInit);
|
||||
// 只在初始化时重置使用计数
|
||||
this.markProviderHealthy(providerType, providerConfig);
|
||||
this._log('debug', `Health check for ${providerConfig.uuid} (${providerType}): Still Healthy`);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -318,13 +318,18 @@ export async function serveStaticFiles(pathParam, res) {
|
|||
* 动态导入config-manager并重新初始化配置
|
||||
* @returns {Promise<Object>} 返回重载后的配置对象
|
||||
*/
|
||||
async function reloadConfig() {
|
||||
async function reloadConfig(providerPoolManager) {
|
||||
try {
|
||||
// Import config manager dynamically
|
||||
const { initializeConfig } = await import('./config-manager.js');
|
||||
|
||||
// Reload main config
|
||||
const newConfig = await initializeConfig(process.argv.slice(2), 'config.json');
|
||||
// Update provider pool manager if available
|
||||
if (providerPoolManager) {
|
||||
providerPoolManager.providerPools = newConfig.providerPools;
|
||||
providerPoolManager.initializeProviderStatus();
|
||||
}
|
||||
|
||||
// Update global CONFIG
|
||||
Object.assign(CONFIG, newConfig);
|
||||
|
|
@ -409,7 +414,17 @@ export async function handleUIApiRequests(method, pathParam, req, res, currentCo
|
|||
const tempFilePath = req.file.path;
|
||||
|
||||
// 根据实际的provider移动文件到正确的目录
|
||||
const targetDir = path.join(process.cwd(), 'configs', provider);
|
||||
let targetDir = path.join(process.cwd(), 'configs', provider);
|
||||
|
||||
// 如果是kiro类型的凭证,需要再包裹一层文件夹
|
||||
if (provider === 'kiro') {
|
||||
// 使用时间戳作为子文件夹名称,确保每个上传的文件都有独立的目录
|
||||
const timestamp = Date.now();
|
||||
const originalNameWithoutExt = path.parse(req.file.originalname).name;
|
||||
const subFolder = `${timestamp}_${originalNameWithoutExt}`;
|
||||
targetDir = path.join(targetDir, subFolder);
|
||||
}
|
||||
|
||||
await fs.mkdir(targetDir, { recursive: true });
|
||||
|
||||
const targetFilePath = path.join(targetDir, req.file.filename);
|
||||
|
|
@ -1149,7 +1164,7 @@ export async function handleUIApiRequests(method, pathParam, req, res, currentCo
|
|||
if (method === 'POST' && pathParam === '/api/reload-config') {
|
||||
try {
|
||||
// 调用重载配置函数
|
||||
const newConfig = await reloadConfig();
|
||||
const newConfig = await reloadConfig(providerPoolManager);
|
||||
|
||||
// 广播更新事件
|
||||
broadcastEvent('config_update', {
|
||||
|
|
@ -1575,7 +1590,8 @@ async function scanOAuthDirectory(dirPath, usedPaths, currentConfig) {
|
|||
} else if (file.isDirectory()) {
|
||||
// 递归扫描子目录(限制深度)
|
||||
const relativePath = path.relative(process.cwd(), fullPath);
|
||||
if (relativePath.split(path.sep).length < 3) { // 最大深度3层
|
||||
// 最大深度4层,以支持 configs/kiro/{subfolder}/file.json 这样的结构
|
||||
if (relativePath.split(path.sep).length < 4) {
|
||||
const subFiles = await scanOAuthDirectory(fullPath, usedPaths, currentConfig);
|
||||
oauthFiles.push(...subFiles);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,10 +67,10 @@ function initEventListeners() {
|
|||
});
|
||||
|
||||
// 提供商池配置监听
|
||||
const providerPoolsInput = document.getElementById('providerPoolsFilePath');
|
||||
if (providerPoolsInput) {
|
||||
providerPoolsInput.addEventListener('input', handleProviderPoolsConfigChange);
|
||||
}
|
||||
// const providerPoolsInput = document.getElementById('providerPoolsFilePath');
|
||||
// if (providerPoolsInput) {
|
||||
// providerPoolsInput.addEventListener('input', handleProviderPoolsConfigChange);
|
||||
// }
|
||||
|
||||
// 日志容器滚动
|
||||
if (elements.logsContainer) {
|
||||
|
|
|
|||
|
|
@ -623,8 +623,8 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group pool-section">
|
||||
<label for="providerPoolsFilePath">提供商池配置文件路径</label>
|
||||
<input type="text" id="providerPoolsFilePath" class="form-control" value="" placeholder="例如: provider_pools.json">
|
||||
<label for="providerPoolsFilePath">提供商池配置文件路径(不能为空)</label>
|
||||
<input type="text" id="providerPoolsFilePath" class="form-control" value="" placeholder="默认: provider_pools.json">
|
||||
<small class="form-text">配置了提供商池后,默认使用提供商池的配置,提供商池配置失效降级到默认配置</small>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue