fix(worker): 防止事务泄漏并恢复滞留队列
为 PostgreSQL 连接增加可配置的事务空闲与锁等待超时,并在请求取消或 Worker 退出后使用独立有界上下文回滚事务。\n\n恢复过期任务时按批次使用 SKIP LOCKED,周期重建缺失或终态 River Job;锁等待超时只在确认尚未提交上游时安全重排,避免重复执行和重复结算。\n\n验证:完整 Go 测试、go vet、生产 Kustomize 渲染、gofmt 与 git diff --check 均通过。
This commit is contained in:
@@ -144,6 +144,13 @@ func TestProcessRolePrecedenceAndCompatibility(t *testing.T) {
|
||||
|
||||
func TestValidateProcessRoleAndDatabasePool(t *testing.T) {
|
||||
cfg := Load()
|
||||
if cfg.DatabaseIdleInTransactionTimeoutSeconds != 60 || cfg.DatabaseLockTimeoutSeconds != 30 {
|
||||
t.Fatalf(
|
||||
"database transaction timeouts = %d/%d, want 60/30",
|
||||
cfg.DatabaseIdleInTransactionTimeoutSeconds,
|
||||
cfg.DatabaseLockTimeoutSeconds,
|
||||
)
|
||||
}
|
||||
cfg.ProcessRole = "invalid"
|
||||
if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "PROCESS_ROLE") {
|
||||
t.Fatalf("Validate() error = %v, want invalid process role", err)
|
||||
@@ -154,6 +161,21 @@ func TestValidateProcessRoleAndDatabasePool(t *testing.T) {
|
||||
t.Fatalf("Validate() error = %v, want invalid database max conns", err)
|
||||
}
|
||||
cfg.DatabaseMaxConns = 16
|
||||
cfg.DatabaseIdleInTransactionTimeoutSeconds = 3601
|
||||
if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "IDLE_IN_TRANSACTION") {
|
||||
t.Fatalf("Validate() error = %v, want invalid idle transaction timeout", err)
|
||||
}
|
||||
cfg.DatabaseIdleInTransactionTimeoutSeconds = 60
|
||||
cfg.DatabaseLockTimeoutSeconds = 3601
|
||||
if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "LOCK_TIMEOUT") {
|
||||
t.Fatalf("Validate() error = %v, want invalid lock timeout", err)
|
||||
}
|
||||
cfg.DatabaseLockTimeoutSeconds = 30
|
||||
t.Setenv("AI_GATEWAY_DATABASE_LOCK_TIMEOUT_SECONDS", "not-an-integer")
|
||||
if err := Load().Validate(); err == nil || !strings.Contains(err.Error(), "LOCK_TIMEOUT") {
|
||||
t.Fatalf("Validate() error = %v, want invalid non-integer lock timeout", err)
|
||||
}
|
||||
t.Setenv("AI_GATEWAY_DATABASE_LOCK_TIMEOUT_SECONDS", "30")
|
||||
cfg.MediaMaterializationConcurrency = 257
|
||||
if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "MEDIA_MATERIALIZATION_CONCURRENCY") {
|
||||
t.Fatalf("Validate() error = %v, want invalid media materialization concurrency", err)
|
||||
|
||||
Reference in New Issue
Block a user