fix(acceptance): 隔离容量压测并稳定数据库连接
将协议模拟验收的供应商并发限额与 Worker 容量门禁分离,真实金丝雀继续保留生产限流。readyz 改用关键连接池并预热关键及 River 池,延长生产连接空闲周期,降低跨地域连接抖动。失败 Run 现在可以原子替换且失败报告记录任务数量,避免 validation 之间短暂放开正式流量。\n\n验证:Go 全量测试、go vet、PostgreSQL 集成测试、ShellCheck、迁移安全、发布脚本、pnpm lint/test/build、OpenAPI 无漂移均通过。
This commit is contained in:
@@ -146,7 +146,11 @@ func (s *Service) buildTaskAdmissionPlanForCurrentBinding(
|
||||
ModelType: modelType,
|
||||
}, nil
|
||||
}
|
||||
if err := s.store.CheckRateLimits(ctx, s.rateLimitReservations(ctx, user, candidate, body)); err != nil {
|
||||
reservations := acceptanceInfrastructureReservations(
|
||||
task,
|
||||
s.rateLimitReservations(ctx, user, candidate, body),
|
||||
)
|
||||
if err := s.store.CheckRateLimits(ctx, reservations); err != nil {
|
||||
return taskAdmissionPlan{}, err
|
||||
}
|
||||
return taskAdmissionPlan{
|
||||
@@ -206,8 +210,17 @@ func acceptanceAdmissionScopes(task store.GatewayTask, scopes []store.AdmissionS
|
||||
}
|
||||
out := append([]store.AdmissionScope(nil), scopes...)
|
||||
for index := range out {
|
||||
// Protocol-emulated acceptance measures Gateway and Worker capacity, so
|
||||
// the isolated Run is bounded by the worker_capacity scope instead of a
|
||||
// production supplier quota. The real acceptance_canary path deliberately
|
||||
// retains the production platform-model concurrency limit.
|
||||
if task.RunMode == "acceptance" && out[index].ScopeType == "platform_model" {
|
||||
out[index].ConcurrentLimit = 0
|
||||
}
|
||||
if out[index].ConcurrentLimit <= 0 {
|
||||
continue
|
||||
if task.RunMode != "acceptance" || out[index].ScopeType != "platform_model" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
out[index].QueueLimit = acceptanceQueueLimit
|
||||
out[index].MaxWaitSeconds = acceptanceQueueMaxWait
|
||||
@@ -215,6 +228,23 @@ func acceptanceAdmissionScopes(task store.GatewayTask, scopes []store.AdmissionS
|
||||
return out
|
||||
}
|
||||
|
||||
func acceptanceInfrastructureReservations(
|
||||
task store.GatewayTask,
|
||||
reservations []store.RateLimitReservation,
|
||||
) []store.RateLimitReservation {
|
||||
if task.RunMode != "acceptance" {
|
||||
return reservations
|
||||
}
|
||||
out := make([]store.RateLimitReservation, 0, len(reservations))
|
||||
for _, reservation := range reservations {
|
||||
if reservation.ScopeType == "platform_model" && reservation.Metric == "concurrent" {
|
||||
continue
|
||||
}
|
||||
out = append(out, reservation)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *Service) loadAsyncTaskAdmission(ctx context.Context, task store.GatewayTask) (*store.TaskAdmission, error) {
|
||||
if !task.AsyncMode {
|
||||
return nil, nil
|
||||
@@ -420,7 +450,11 @@ func (s *Service) ensureCandidateAdmission(
|
||||
}
|
||||
return store.TaskAdmissionResult{}, false, nil
|
||||
}
|
||||
if err := s.store.CheckRateLimits(ctx, s.rateLimitReservations(ctx, user, candidate, body)); err != nil {
|
||||
reservations := acceptanceInfrastructureReservations(
|
||||
task,
|
||||
s.rateLimitReservations(ctx, user, candidate, body),
|
||||
)
|
||||
if err := s.store.CheckRateLimits(ctx, reservations); err != nil {
|
||||
return store.TaskAdmissionResult{}, true, err
|
||||
}
|
||||
plan := taskAdmissionPlan{
|
||||
|
||||
Reference in New Issue
Block a user