fix(acceptance): 按隔离额度执行平台降级路由

让 acceptance 候选负载读取同一 Run ID 下的并发、RPM 和 TPM 计数器,并在单个平台模型额度不足时继续尝试下一候选,生产与 canary 额度作用域保持不变。\n\n补齐本地容量控制器对宁波和香港测试 Worker 的最小 RBAC,避免初次应用生产反亲和配置时发生滚动死锁,并将突发负载对齐到完整限流窗口。\n\n验证:\n- go test ./internal/runner ./internal/store -count=1\n- go vet ./internal/runner ./internal/store\n- bash -n scripts/acceptance/local-cluster.sh scripts/acceptance/provider-burst.sh scripts/acceptance/run-local-acceptance.sh\n- shellcheck -x scripts/acceptance/local-cluster.sh scripts/acceptance/provider-burst.sh scripts/acceptance/run-local-acceptance.sh\n- kubectl apply --dry-run=client -f deploy/kubernetes/local-acceptance/capacity-controller-rbac.yaml
This commit is contained in:
2026-08-03 12:06:09 +08:00
parent 8485f14bc4
commit d740e9f676
7 changed files with 67 additions and 4 deletions
+6 -4
View File
@@ -17,6 +17,7 @@ type ListModelCandidatesOptions struct {
CacheAffinityKey string
CacheAffinityKeys []string
CacheAffinityPolicy map[string]any
QuotaScopePrefix string
}
func (s *Store) ListModelCandidates(ctx context.Context, model string, modelType string, user *auth.User, options ...ListModelCandidatesOptions) ([]RuntimeModelCandidate, error) {
@@ -102,7 +103,7 @@ LEFT JOIN (
AND released_at IS NULL
AND expires_at > statement_timestamp()
GROUP BY scope_key
) con ON con.scope_key = m.id::text
) con ON con.scope_key = $5::text || m.id::text
LEFT JOIN (
SELECT queued_sources.platform_model_id, COUNT(DISTINCT queued_sources.task_id) AS waiting
FROM (
@@ -137,7 +138,7 @@ LEFT JOIN (
AND metric = 'rpm'
AND reset_at > now()
ORDER BY scope_key, window_start DESC
) rpm ON rpm.scope_key = m.id::text
) rpm ON rpm.scope_key = $5::text || m.id::text
LEFT JOIN (
SELECT scope_key, SUM(used_value) AS used_value, SUM(reserved_value) AS reserved_value
FROM gateway_rate_limit_counters
@@ -145,7 +146,7 @@ LEFT JOIN (
AND metric LIKE 'tpm%'
AND reset_at > now()
GROUP BY scope_key
) tpm ON tpm.scope_key = m.id::text
) tpm ON tpm.scope_key = $5::text || m.id::text
WHERE p.status = 'enabled'
AND p.deleted_at IS NULL
AND m.enabled = true
@@ -170,7 +171,7 @@ WHERE p.status = 'enabled'
COALESCE(s.running_count, 0) ASC,
COALESCE(s.waiting_count, 0) ASC,
COALESCE(s.last_assigned_at, to_timestamp(0)) ASC,
m.created_at ASC`, exactModel, modelType, listOptions.CacheAffinityKeys, cacheAffinityStaleAfterSeconds(listOptions.CacheAffinityPolicy))
m.created_at ASC`, exactModel, modelType, listOptions.CacheAffinityKeys, cacheAffinityStaleAfterSeconds(listOptions.CacheAffinityPolicy), listOptions.QuotaScopePrefix)
if err != nil {
return nil, err
}
@@ -472,6 +473,7 @@ func normalizeListModelCandidatesOptions(modelType string, options ...ListModelC
}
out := options[0]
out.CacheAffinityKey = strings.TrimSpace(out.CacheAffinityKey)
out.QuotaScopePrefix = strings.TrimSpace(out.QuotaScopePrefix)
out.CacheAffinityKeys = normalizedCacheAffinityKeys(out.CacheAffinityKey, out.CacheAffinityKeys)
if len(out.CacheAffinityKeys) > 0 {
out.CacheAffinityKey = out.CacheAffinityKeys[0]