fix(provider): 避免重复增加provider使用计数

当从provider池重新选择服务时跳过usageCount增加,因为初次选择时已经增加过。同时优化token刷新逻辑,合并强制刷新和即将过期的检查条件。
This commit is contained in:
hex2077 2025-12-04 12:53:17 +08:00
parent bc3725e901
commit 211d677d00
4 changed files with 25 additions and 20 deletions

View file

@ -395,9 +395,10 @@ export async function handleContentGenerationRequest(req, res, service, endpoint
console.log(`[Content Generation] Model: ${model}, Stream: ${isStream}`); console.log(`[Content Generation] Model: ${model}, Stream: ${isStream}`);
// 2.5. 如果使用了提供商池,根据模型重新选择提供商 // 2.5. 如果使用了提供商池,根据模型重新选择提供商
// 注意:这里使用 skipUsageCount: true因为初次选择时已经增加了 usageCount
if (providerPoolManager && CONFIG.providerPools && CONFIG.providerPools[CONFIG.MODEL_PROVIDER]) { if (providerPoolManager && CONFIG.providerPools && CONFIG.providerPools[CONFIG.MODEL_PROVIDER]) {
const { getApiService } = await import('./service-manager.js'); const { getApiService } = await import('./service-manager.js');
service = await getApiService(CONFIG, model); service = await getApiService(CONFIG, model, { skipUsageCount: true });
console.log(`[Content Generation] Re-selected service adapter based on model: ${model}`); console.log(`[Content Generation] Re-selected service adapter based on model: ${model}`);
} }

View file

@ -249,11 +249,12 @@ export class AntigravityApiService {
} }
async initializeAuth(forceRefresh = false) { async initializeAuth(forceRefresh = false) {
if (this.authClient.credentials.access_token && !forceRefresh) { // 检查是否需要刷新 Token
// 检查 Token 是否即将过期 const needsRefresh = forceRefresh || this.isTokenExpiringSoon();
if (!this.isTokenExpiringSoon()) {
return; if (this.authClient.credentials.access_token && !needsRefresh) {
} // Token 有效且不需要刷新
return;
} }
// Antigravity 不支持 base64 配置,直接使用文件路径 // Antigravity 不支持 base64 配置,直接使用文件路径
@ -265,13 +266,13 @@ export class AntigravityApiService {
this.authClient.setCredentials(credentials); this.authClient.setCredentials(credentials);
console.log('[Antigravity Auth] Authentication configured successfully from file.'); console.log('[Antigravity Auth] Authentication configured successfully from file.');
if (forceRefresh) { if (needsRefresh) {
console.log('[Antigravity Auth] Forcing token refresh...'); console.log('[Antigravity Auth] Token expiring soon or force refresh requested. Refreshing token...');
const { credentials: newCredentials } = await this.authClient.refreshAccessToken(); const { credentials: newCredentials } = await this.authClient.refreshAccessToken();
this.authClient.setCredentials(newCredentials); this.authClient.setCredentials(newCredentials);
// 保存刷新后的凭证 // 保存刷新后的凭证到文件
await fs.writeFile(credPath, JSON.stringify(newCredentials, null, 2)); await fs.writeFile(credPath, JSON.stringify(newCredentials, null, 2));
console.log('[Antigravity Auth] Token refreshed and saved successfully.'); console.log(`[Antigravity Auth] Token refreshed and saved to ${credPath} successfully.`);
} }
} catch (error) { } catch (error) {
console.error('[Antigravity Auth] Error initializing authentication:', error.code); console.error('[Antigravity Auth] Error initializing authentication:', error.code);

View file

@ -98,7 +98,7 @@ export class ProviderPoolManager {
* @param {string} [requestedModel] - Optional. The model name to filter providers by. * @param {string} [requestedModel] - Optional. The model name to filter providers by.
* @returns {object|null} The selected provider's configuration, or null if no healthy provider is found. * @returns {object|null} The selected provider's configuration, or null if no healthy provider is found.
*/ */
selectProvider(providerType, requestedModel = null) { selectProvider(providerType, requestedModel = null, options = {}) {
// 参数校验 // 参数校验
if (!providerType || typeof providerType !== 'string') { if (!providerType || typeof providerType !== 'string') {
this._log('error', `Invalid providerType: ${providerType}`); this._log('error', `Invalid providerType: ${providerType}`);
@ -147,14 +147,15 @@ export class ProviderPoolManager {
// 更新下次轮询的索引 // 更新下次轮询的索引
this.roundRobinIndex[indexKey] = (currentIndex + 1) % availableAndHealthyProviders.length; this.roundRobinIndex[indexKey] = (currentIndex + 1) % availableAndHealthyProviders.length;
// 更新使用信息 // 更新使用信息(除非明确跳过)
selected.config.lastUsed = new Date().toISOString(); if (!options.skipUsageCount) {
selected.config.usageCount++; selected.config.lastUsed = new Date().toISOString();
selected.config.usageCount++;
// 使用防抖保存
this._debouncedSave(providerType);
}
this._log('debug', `Selected provider for ${providerType} (round-robin): ${selected.config.uuid}${requestedModel ? ` for model: ${requestedModel}` : ''}`); this._log('debug', `Selected provider for ${providerType} (round-robin): ${selected.config.uuid}${requestedModel ? ` for model: ${requestedModel}` : ''}${options.skipUsageCount ? ' (skip usage count)' : ''}`);
// 使用防抖保存
this._debouncedSave(providerType);
return selected.config; return selected.config;
} }

View file

@ -60,13 +60,15 @@ export async function initApiService(config) {
* Get API service adapter, considering provider pools * Get API service adapter, considering provider pools
* @param {Object} config - The current request configuration * @param {Object} config - The current request configuration
* @param {string} [requestedModel] - Optional. The model name to filter providers by. * @param {string} [requestedModel] - Optional. The model name to filter providers by.
* @param {Object} [options] - Optional. Additional options.
* @param {boolean} [options.skipUsageCount] - Optional. If true, skip incrementing usage count.
* @returns {Promise<Object>} The API service adapter * @returns {Promise<Object>} The API service adapter
*/ */
export async function getApiService(config, requestedModel = null) { export async function getApiService(config, requestedModel = null, options = {}) {
let serviceConfig = config; let serviceConfig = config;
if (providerPoolManager && config.providerPools && config.providerPools[config.MODEL_PROVIDER]) { if (providerPoolManager && config.providerPools && config.providerPools[config.MODEL_PROVIDER]) {
// 如果有号池管理器,并且当前模型提供者类型有对应的号池,则从号池中选择一个提供者配置 // 如果有号池管理器,并且当前模型提供者类型有对应的号池,则从号池中选择一个提供者配置
const selectedProviderConfig = providerPoolManager.selectProvider(config.MODEL_PROVIDER, requestedModel); const selectedProviderConfig = providerPoolManager.selectProvider(config.MODEL_PROVIDER, requestedModel, options);
if (selectedProviderConfig) { if (selectedProviderConfig) {
// 合并选中的提供者配置到当前请求的 config 中 // 合并选中的提供者配置到当前请求的 config 中
serviceConfig = deepmerge(config, selectedProviderConfig); serviceConfig = deepmerge(config, selectedProviderConfig);