mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 09:38:02 +00:00
fix: 修复专属账号停止调度后仍能使用的问题
- 在 selectAccountForApiKey 方法中为所有专属账号类型添加 schedulable 检查 - 在 _getAllAvailableAccounts 方法中为所有专属账号类型添加 schedulable 检查 - 改进日志输出,显示账号不可用的具体原因(isActive、status、schedulable 状态) 问题描述: 当 Claude Console/OAuth/Bedrock 账号设置为专属账号并停止调度(schedulable=false)后, 系统仍然会使用该账号,没有正确回退到账号池。 修复内容: 1. Claude OAuth 账号:添加 this._isSchedulable(boundAccount.schedulable) 检查 2. Claude Console 账号:添加 this._isSchedulable(boundConsoleAccount.schedulable) 检查 3. Bedrock 账号:添加 this._isSchedulable(boundBedrockAccountResult.data.schedulable) 检查 兼容性: _isSchedulable 方法已处理向后兼容,当 schedulable 字段为 undefined/null 时默认返回 true 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -107,7 +107,12 @@ class UnifiedClaudeScheduler {
|
|||||||
|
|
||||||
// 普通专属账户
|
// 普通专属账户
|
||||||
const boundAccount = await redis.getClaudeAccount(apiKeyData.claudeAccountId)
|
const boundAccount = await redis.getClaudeAccount(apiKeyData.claudeAccountId)
|
||||||
if (boundAccount && boundAccount.isActive === 'true' && boundAccount.status !== 'error') {
|
if (
|
||||||
|
boundAccount &&
|
||||||
|
boundAccount.isActive === 'true' &&
|
||||||
|
boundAccount.status !== 'error' &&
|
||||||
|
this._isSchedulable(boundAccount.schedulable)
|
||||||
|
) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`🎯 Using bound dedicated Claude OAuth account: ${boundAccount.name} (${apiKeyData.claudeAccountId}) for API key ${apiKeyData.name}`
|
`🎯 Using bound dedicated Claude OAuth account: ${boundAccount.name} (${apiKeyData.claudeAccountId}) for API key ${apiKeyData.name}`
|
||||||
)
|
)
|
||||||
@@ -117,7 +122,7 @@ class UnifiedClaudeScheduler {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`⚠️ Bound Claude OAuth account ${apiKeyData.claudeAccountId} is not available, falling back to pool`
|
`⚠️ Bound Claude OAuth account ${apiKeyData.claudeAccountId} is not available (isActive: ${boundAccount?.isActive}, status: ${boundAccount?.status}, schedulable: ${boundAccount?.schedulable}), falling back to pool`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +135,8 @@ class UnifiedClaudeScheduler {
|
|||||||
if (
|
if (
|
||||||
boundConsoleAccount &&
|
boundConsoleAccount &&
|
||||||
boundConsoleAccount.isActive === true &&
|
boundConsoleAccount.isActive === true &&
|
||||||
boundConsoleAccount.status === 'active'
|
boundConsoleAccount.status === 'active' &&
|
||||||
|
this._isSchedulable(boundConsoleAccount.schedulable)
|
||||||
) {
|
) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`🎯 Using bound dedicated Claude Console account: ${boundConsoleAccount.name} (${apiKeyData.claudeConsoleAccountId}) for API key ${apiKeyData.name}`
|
`🎯 Using bound dedicated Claude Console account: ${boundConsoleAccount.name} (${apiKeyData.claudeConsoleAccountId}) for API key ${apiKeyData.name}`
|
||||||
@@ -141,7 +147,7 @@ class UnifiedClaudeScheduler {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`⚠️ Bound Claude Console account ${apiKeyData.claudeConsoleAccountId} is not available, falling back to pool`
|
`⚠️ Bound Claude Console account ${apiKeyData.claudeConsoleAccountId} is not available (isActive: ${boundConsoleAccount?.isActive}, status: ${boundConsoleAccount?.status}, schedulable: ${boundConsoleAccount?.schedulable}), falling back to pool`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,7 +157,11 @@ class UnifiedClaudeScheduler {
|
|||||||
const boundBedrockAccountResult = await bedrockAccountService.getAccount(
|
const boundBedrockAccountResult = await bedrockAccountService.getAccount(
|
||||||
apiKeyData.bedrockAccountId
|
apiKeyData.bedrockAccountId
|
||||||
)
|
)
|
||||||
if (boundBedrockAccountResult.success && boundBedrockAccountResult.data.isActive === true) {
|
if (
|
||||||
|
boundBedrockAccountResult.success &&
|
||||||
|
boundBedrockAccountResult.data.isActive === true &&
|
||||||
|
this._isSchedulable(boundBedrockAccountResult.data.schedulable)
|
||||||
|
) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`🎯 Using bound dedicated Bedrock account: ${boundBedrockAccountResult.data.name} (${apiKeyData.bedrockAccountId}) for API key ${apiKeyData.name}`
|
`🎯 Using bound dedicated Bedrock account: ${boundBedrockAccountResult.data.name} (${apiKeyData.bedrockAccountId}) for API key ${apiKeyData.name}`
|
||||||
)
|
)
|
||||||
@@ -161,7 +171,7 @@ class UnifiedClaudeScheduler {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`⚠️ Bound Bedrock account ${apiKeyData.bedrockAccountId} is not available, falling back to pool`
|
`⚠️ Bound Bedrock account ${apiKeyData.bedrockAccountId} is not available (isActive: ${boundBedrockAccountResult?.data?.isActive}, schedulable: ${boundBedrockAccountResult?.data?.schedulable}), falling back to pool`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,7 +261,8 @@ class UnifiedClaudeScheduler {
|
|||||||
boundAccount.isActive === 'true' &&
|
boundAccount.isActive === 'true' &&
|
||||||
boundAccount.status !== 'error' &&
|
boundAccount.status !== 'error' &&
|
||||||
boundAccount.status !== 'blocked' &&
|
boundAccount.status !== 'blocked' &&
|
||||||
boundAccount.status !== 'temp_error'
|
boundAccount.status !== 'temp_error' &&
|
||||||
|
this._isSchedulable(boundAccount.schedulable)
|
||||||
) {
|
) {
|
||||||
const isRateLimited = await claudeAccountService.isAccountRateLimited(boundAccount.id)
|
const isRateLimited = await claudeAccountService.isAccountRateLimited(boundAccount.id)
|
||||||
if (!isRateLimited) {
|
if (!isRateLimited) {
|
||||||
@@ -269,7 +280,9 @@ class UnifiedClaudeScheduler {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn(`⚠️ Bound Claude OAuth account ${apiKeyData.claudeAccountId} is not available`)
|
logger.warn(
|
||||||
|
`⚠️ Bound Claude OAuth account ${apiKeyData.claudeAccountId} is not available (isActive: ${boundAccount?.isActive}, status: ${boundAccount?.status}, schedulable: ${boundAccount?.schedulable})`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +294,8 @@ class UnifiedClaudeScheduler {
|
|||||||
if (
|
if (
|
||||||
boundConsoleAccount &&
|
boundConsoleAccount &&
|
||||||
boundConsoleAccount.isActive === true &&
|
boundConsoleAccount.isActive === true &&
|
||||||
boundConsoleAccount.status === 'active'
|
boundConsoleAccount.status === 'active' &&
|
||||||
|
this._isSchedulable(boundConsoleAccount.schedulable)
|
||||||
) {
|
) {
|
||||||
// 主动触发一次额度检查
|
// 主动触发一次额度检查
|
||||||
try {
|
try {
|
||||||
@@ -317,7 +331,7 @@ class UnifiedClaudeScheduler {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`⚠️ Bound Claude Console account ${apiKeyData.claudeConsoleAccountId} is not available`
|
`⚠️ Bound Claude Console account ${apiKeyData.claudeConsoleAccountId} is not available (isActive: ${boundConsoleAccount?.isActive}, status: ${boundConsoleAccount?.status}, schedulable: ${boundConsoleAccount?.schedulable})`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -327,7 +341,11 @@ class UnifiedClaudeScheduler {
|
|||||||
const boundBedrockAccountResult = await bedrockAccountService.getAccount(
|
const boundBedrockAccountResult = await bedrockAccountService.getAccount(
|
||||||
apiKeyData.bedrockAccountId
|
apiKeyData.bedrockAccountId
|
||||||
)
|
)
|
||||||
if (boundBedrockAccountResult.success && boundBedrockAccountResult.data.isActive === true) {
|
if (
|
||||||
|
boundBedrockAccountResult.success &&
|
||||||
|
boundBedrockAccountResult.data.isActive === true &&
|
||||||
|
this._isSchedulable(boundBedrockAccountResult.data.schedulable)
|
||||||
|
) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`🎯 Using bound dedicated Bedrock account: ${boundBedrockAccountResult.data.name} (${apiKeyData.bedrockAccountId})`
|
`🎯 Using bound dedicated Bedrock account: ${boundBedrockAccountResult.data.name} (${apiKeyData.bedrockAccountId})`
|
||||||
)
|
)
|
||||||
@@ -341,7 +359,9 @@ class UnifiedClaudeScheduler {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
logger.warn(`⚠️ Bound Bedrock account ${apiKeyData.bedrockAccountId} is not available`)
|
logger.warn(
|
||||||
|
`⚠️ Bound Bedrock account ${apiKeyData.bedrockAccountId} is not available (isActive: ${boundBedrockAccountResult?.data?.isActive}, schedulable: ${boundBedrockAccountResult?.data?.schedulable})`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user