fix(acceptance): 隔离容量压测并稳定数据库连接

将协议模拟验收的供应商并发限额与 Worker 容量门禁分离,真实金丝雀继续保留生产限流。readyz 改用关键连接池并预热关键及 River 池,延长生产连接空闲周期,降低跨地域连接抖动。失败 Run 现在可以原子替换且失败报告记录任务数量,避免 validation 之间短暂放开正式流量。\n\n验证:Go 全量测试、go vet、PostgreSQL 集成测试、ShellCheck、迁移安全、发布脚本、pnpm lint/test/build、OpenAPI 无漂移均通过。
This commit is contained in:
2026-08-01 19:29:08 +08:00
parent 89a0ff7e99
commit 92e328a575
11 changed files with 277 additions and 42 deletions
+34 -3
View File
@@ -209,9 +209,6 @@ FOR UPDATE`, SystemSettingGatewayTrafficMode).Scan(&currentValue); err != nil {
if err := json.Unmarshal(currentValue, &current); err != nil {
return GatewayTrafficMode{}, err
}
if normalizeTrafficMode(current.Mode) != "live" {
return GatewayTrafficMode{}, ErrAcceptanceStateConflict
}
run, err := scanAcceptanceRun(tx.QueryRow(ctx, `
SELECT `+acceptanceRunColumns+`
FROM gateway_acceptance_runs
@@ -223,6 +220,40 @@ FOR UPDATE`, strings.TrimSpace(runID)))
if run.Status != "pending" && run.Status != "failed" {
return GatewayTrafficMode{}, ErrAcceptanceStateConflict
}
switch normalizeTrafficMode(current.Mode) {
case "live":
case "validation":
if current.RunID == "" || current.RunID == run.ID {
return GatewayTrafficMode{}, ErrAcceptanceStateConflict
}
previous, previousErr := scanAcceptanceRun(tx.QueryRow(ctx, `
SELECT `+acceptanceRunColumns+`
FROM gateway_acceptance_runs
WHERE id = $1::uuid
FOR UPDATE`, current.RunID))
if previousErr != nil {
return GatewayTrafficMode{}, previousErr
}
if previous.Status != "failed" ||
previous.ReleaseSHA != current.ReleaseSHA ||
previous.APIImageDigest != current.APIImageDigest ||
previous.WorkerImageDigest != current.WorkerImageDigest {
return GatewayTrafficMode{}, ErrAcceptanceStateConflict
}
var activeTasks int
if err := tx.QueryRow(ctx, `
SELECT count(*)
FROM gateway_tasks
WHERE acceptance_run_id = $1::uuid
AND status IN ('queued', 'running')`, previous.ID).Scan(&activeTasks); err != nil {
return GatewayTrafficMode{}, err
}
if activeTasks != 0 {
return GatewayTrafficMode{}, ErrAcceptanceStateConflict
}
default:
return GatewayTrafficMode{}, ErrAcceptanceStateConflict
}
next := GatewayTrafficMode{
Mode: "validation",
RunID: run.ID,