fix(admission): 限制媒体任务准入锁等待并发

媒体请求从认证、任务创建到异步准入登记共用可配置的请求并发令牌,完成登记后立即释放。这样仍会尽早丢弃 Base64 正文,但不会让高并发请求各占一个 PostgreSQL 连接等待 advisory lock。\n\n扩展 Gemini 双角色压力测试,使用生产同档 API/Worker 连接池并记录数据库连接与 advisory lock 峰值。\n\n验证:go test ./... -count=1;go vet ./...;pnpm openapi;迁移安全检查;256 个 256 KiB 异步 Gemini 请求全部通过,连接峰值 45、锁等待峰值 14。
This commit is contained in:
2026-07-31 06:05:54 +08:00
parent 4af86b22ee
commit 4fa44f4c41
3 changed files with 58 additions and 14 deletions
+8 -5
View File
@@ -164,13 +164,12 @@ func (s *Server) geminiGenerateContent(w http.ResponseWriter, r *http.Request) {
writeGeminiTaskError(status, err.Error(), nil, clients.ErrorCode(err))
return
}
// The queued task only needs the materialized assetRef. Release the native
// Base64 request body before it waits for distributed admission or an
// upstream response.
// The queued task only needs the materialized assetRef. Drop the native
// Base64 request body now, but retain the lightweight request slot until
// distributed admission is durably registered. This prevents a burst from
// turning advisory-lock waiters into one PostgreSQL connection per request.
native = nil
mapping.Body = nil
releaseRequestBody()
releaseRequestBody = nil
runMode, err := s.admittedTaskRunMode(admission, prepared.Body)
if err != nil {
writeTaskTrafficError(w, err, clients.ProtocolGeminiGenerateContent)
@@ -237,6 +236,8 @@ func (s *Server) geminiGenerateContent(w http.ResponseWriter, r *http.Request) {
runCtx, cancelRun := s.requestExecutionContext(r)
defer cancelRun()
if streamMode {
releaseRequestBody()
releaseRequestBody = nil
s.writeGeminiGenerateContentStream(runCtx, w, r, task, user, mapping.Model, writeGeminiTaskError)
return
}
@@ -248,6 +249,8 @@ func (s *Server) geminiGenerateContent(w http.ResponseWriter, r *http.Request) {
writeGeminiTaskError(statusFromRunError(err), runErrorMessage(err), runErrorDetails(err), runErrorCode(err))
return
}
releaseRequestBody()
releaseRequestBody = nil
task, err = s.runner.WaitForTaskCompletion(runCtx, task.ID)
if err != nil || !requestStillConnected(r) {
return