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:
@@ -103,6 +103,7 @@ func (s *Service) buildTaskAdmissionPlanForCurrentBinding(
|
||||
CacheAffinityKey: cacheAffinityKeys.Primary,
|
||||
CacheAffinityKeys: cacheAffinityKeys.Lookup,
|
||||
CacheAffinityPolicy: runnerPolicy.CacheAffinityPolicy,
|
||||
QuotaScopePrefix: acceptanceQuotaScopePrefix(task),
|
||||
})
|
||||
if err == nil {
|
||||
candidates, err = filterCandidatesByRequestedPlatform(candidates, body)
|
||||
@@ -120,6 +121,7 @@ func (s *Service) buildTaskAdmissionPlanForCurrentBinding(
|
||||
return taskAdmissionPlan{}, err
|
||||
}
|
||||
candidates, _ = pinCandidatesToTaskAdmission(candidates, admission)
|
||||
var candidateRateLimitErr error
|
||||
for _, candidate := range candidates {
|
||||
available, availabilityErr := s.store.RuntimeCandidateAvailable(ctx, candidate.PlatformID, candidate.PlatformModelID)
|
||||
if availabilityErr != nil {
|
||||
@@ -151,6 +153,13 @@ func (s *Service) buildTaskAdmissionPlanForCurrentBinding(
|
||||
s.rateLimitReservations(ctx, user, candidate, body),
|
||||
)
|
||||
if err := s.store.CheckRateLimits(ctx, reservations); err != nil {
|
||||
var limitErr *store.RateLimitExceededError
|
||||
if errors.As(err, &limitErr) && limitErr.ScopeType == "platform_model" {
|
||||
if candidateRateLimitErr == nil {
|
||||
candidateRateLimitErr = err
|
||||
}
|
||||
continue
|
||||
}
|
||||
return taskAdmissionPlan{}, err
|
||||
}
|
||||
return taskAdmissionPlan{
|
||||
@@ -162,6 +171,9 @@ func (s *Service) buildTaskAdmissionPlanForCurrentBinding(
|
||||
Eligible: true,
|
||||
}, nil
|
||||
}
|
||||
if candidateRateLimitErr != nil {
|
||||
return taskAdmissionPlan{}, candidateRateLimitErr
|
||||
}
|
||||
return taskAdmissionPlan{}, store.ErrNoModelCandidate
|
||||
}
|
||||
|
||||
@@ -239,6 +251,13 @@ func acceptanceScopeKey(task store.GatewayTask, scopeKey string) string {
|
||||
return "acceptance:" + runID + ":" + scopeKey
|
||||
}
|
||||
|
||||
func acceptanceQuotaScopePrefix(task store.GatewayTask) string {
|
||||
if task.RunMode != "acceptance" {
|
||||
return ""
|
||||
}
|
||||
return acceptanceScopeKey(task, "")
|
||||
}
|
||||
|
||||
func (s *Service) loadAsyncTaskAdmission(ctx context.Context, task store.GatewayTask) (*store.TaskAdmission, error) {
|
||||
if !task.AsyncMode {
|
||||
return nil, nil
|
||||
|
||||
Reference in New Issue
Block a user