perf(worker): 公平调度跨节点异步准入锁
持续突发提交会通过 pg_try_advisory_xact_lock 反复抢占全局容量锁,使 Worker 补槽器在首批之后饥饿。\n\n跨进程锁改为 PostgreSQL 公平等待;进程内锁仍保证每个 API 或 Worker 最多一条连接参与等待,30 秒 lock_timeout 会回到原有重试路径,60 秒空闲事务超时继续处理失主会话。\n\n验证:临时 PostgreSQL 18 上 64 并发锁竞争峰值连接不超过 2;Go 全量测试、go vet、gofmt 通过。
This commit is contained in:
@@ -115,18 +115,21 @@ func admissionOperationLockKeys(input TaskAdmissionInput) []string {
|
||||
}
|
||||
|
||||
func tryAdmissionTransactionLock(ctx context.Context, tx pgx.Tx, key string) error {
|
||||
var locked bool
|
||||
if err := tx.QueryRow(
|
||||
// The process-local lock limits this wait to one PostgreSQL connection per
|
||||
// API or Worker process. Let PostgreSQL queue those process representatives
|
||||
// fairly: repeated pg_try_advisory_xact_lock calls let a sustained submit
|
||||
// burst starve the Worker dispatcher that must release queue pressure.
|
||||
// lock_timeout bounds a lost-owner wait and converts it back into the
|
||||
// existing transaction retry path.
|
||||
_, err := tx.Exec(
|
||||
ctx,
|
||||
`SELECT pg_try_advisory_xact_lock(hashtextextended($1, 0))`,
|
||||
`SELECT pg_advisory_xact_lock(hashtextextended($1, 0))`,
|
||||
key,
|
||||
).Scan(&locked); err != nil {
|
||||
return err
|
||||
}
|
||||
if !locked {
|
||||
)
|
||||
if IsPostgresLockTimeout(err) {
|
||||
return errAdmissionLockBusy
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func retryAdmissionOperation[T any](
|
||||
|
||||
Reference in New Issue
Block a user