feat(channel): improve cache strategy and add restriction logging
- Change channel cache TTL from 60s to 10min (reduce unnecessary DB queries) - Actively rebuild cache after CRUD instead of lazy invalidation - Add slog.Warn logging for channel pricing restriction blocks (4 places)
This commit is contained in:
@@ -133,8 +133,8 @@ func (r ChannelMappingResult) ToUsageFields(reqModel, upstreamModel string) Chan
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
channelCacheTTL = 60 * time.Second
|
channelCacheTTL = 10 * time.Minute
|
||||||
channelErrorTTL = 5 * time.Second // DB 错误时的短缓存
|
channelErrorTTL = 5 * time.Second // DB 错误时的短缓存
|
||||||
channelCacheDBTimeout = 10 * time.Second
|
channelCacheDBTimeout = 10 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -333,6 +333,11 @@ func matchingPlatforms(groupPlatform string) []string {
|
|||||||
func (s *ChannelService) invalidateCache() {
|
func (s *ChannelService) invalidateCache() {
|
||||||
s.cache.Store((*channelCache)(nil))
|
s.cache.Store((*channelCache)(nil))
|
||||||
s.cacheSF.Forget("channel_cache")
|
s.cacheSF.Forget("channel_cache")
|
||||||
|
|
||||||
|
// 主动重建缓存,确保 CRUD 后立即生效
|
||||||
|
if _, err := s.buildCache(context.Background()); err != nil {
|
||||||
|
slog.Warn("failed to rebuild channel cache after invalidation", "error", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// matchWildcard 在通配符定价中查找匹配项(最先匹配到优先)
|
// matchWildcard 在通配符定价中查找匹配项(最先匹配到优先)
|
||||||
|
|||||||
@@ -1199,6 +1199,9 @@ func (s *GatewayService) SelectAccountForModelWithExclusions(ctx context.Context
|
|||||||
// Claude Code 限制可能已将 groupID 解析为 fallback group,
|
// Claude Code 限制可能已将 groupID 解析为 fallback group,
|
||||||
// 渠道限制预检查必须使用解析后的分组。
|
// 渠道限制预检查必须使用解析后的分组。
|
||||||
if s.checkChannelPricingRestriction(ctx, groupID, requestedModel) {
|
if s.checkChannelPricingRestriction(ctx, groupID, requestedModel) {
|
||||||
|
slog.Warn("channel pricing restriction blocked request",
|
||||||
|
"group_id", derefGroupID(groupID),
|
||||||
|
"model", requestedModel)
|
||||||
return nil, fmt.Errorf("%w supporting model: %s (channel pricing restriction)", ErrNoAvailableAccounts, requestedModel)
|
return nil, fmt.Errorf("%w supporting model: %s (channel pricing restriction)", ErrNoAvailableAccounts, requestedModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1241,6 +1244,9 @@ func (s *GatewayService) SelectAccountWithLoadAwareness(ctx context.Context, gro
|
|||||||
// Claude Code 限制可能已将 groupID 解析为 fallback group,
|
// Claude Code 限制可能已将 groupID 解析为 fallback group,
|
||||||
// 渠道限制预检查必须使用解析后的分组。
|
// 渠道限制预检查必须使用解析后的分组。
|
||||||
if s.checkChannelPricingRestriction(ctx, groupID, requestedModel) {
|
if s.checkChannelPricingRestriction(ctx, groupID, requestedModel) {
|
||||||
|
slog.Warn("channel pricing restriction blocked request",
|
||||||
|
"group_id", derefGroupID(groupID),
|
||||||
|
"model", requestedModel)
|
||||||
return nil, fmt.Errorf("%w supporting model: %s (channel pricing restriction)", ErrNoAvailableAccounts, requestedModel)
|
return nil, fmt.Errorf("%w supporting model: %s (channel pricing restriction)", ErrNoAvailableAccounts, requestedModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1202,6 +1202,9 @@ func (s *OpenAIGatewayService) SelectAccountForModelWithExclusions(ctx context.C
|
|||||||
|
|
||||||
func (s *OpenAIGatewayService) selectAccountForModelWithExclusions(ctx context.Context, groupID *int64, sessionHash string, requestedModel string, excludedIDs map[int64]struct{}, stickyAccountID int64) (*Account, error) {
|
func (s *OpenAIGatewayService) selectAccountForModelWithExclusions(ctx context.Context, groupID *int64, sessionHash string, requestedModel string, excludedIDs map[int64]struct{}, stickyAccountID int64) (*Account, error) {
|
||||||
if s.checkChannelPricingRestriction(ctx, groupID, requestedModel) {
|
if s.checkChannelPricingRestriction(ctx, groupID, requestedModel) {
|
||||||
|
slog.Warn("channel pricing restriction blocked request",
|
||||||
|
"group_id", derefGroupID(groupID),
|
||||||
|
"model", requestedModel)
|
||||||
return nil, fmt.Errorf("%w supporting model: %s (channel pricing restriction)", ErrNoAvailableAccounts, requestedModel)
|
return nil, fmt.Errorf("%w supporting model: %s (channel pricing restriction)", ErrNoAvailableAccounts, requestedModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1379,6 +1382,9 @@ func (s *OpenAIGatewayService) isBetterAccount(candidate, current *Account) bool
|
|||||||
// SelectAccountWithLoadAwareness selects an account with load-awareness and wait plan.
|
// SelectAccountWithLoadAwareness selects an account with load-awareness and wait plan.
|
||||||
func (s *OpenAIGatewayService) SelectAccountWithLoadAwareness(ctx context.Context, groupID *int64, sessionHash string, requestedModel string, excludedIDs map[int64]struct{}) (*AccountSelectionResult, error) {
|
func (s *OpenAIGatewayService) SelectAccountWithLoadAwareness(ctx context.Context, groupID *int64, sessionHash string, requestedModel string, excludedIDs map[int64]struct{}) (*AccountSelectionResult, error) {
|
||||||
if s.checkChannelPricingRestriction(ctx, groupID, requestedModel) {
|
if s.checkChannelPricingRestriction(ctx, groupID, requestedModel) {
|
||||||
|
slog.Warn("channel pricing restriction blocked request",
|
||||||
|
"group_id", derefGroupID(groupID),
|
||||||
|
"model", requestedModel)
|
||||||
return nil, fmt.Errorf("%w supporting model: %s (channel pricing restriction)", ErrNoAvailableAccounts, requestedModel)
|
return nil, fmt.Errorf("%w supporting model: %s (channel pricing restriction)", ErrNoAvailableAccounts, requestedModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user