perf(queue): 限制大媒体任务内存并消除准入惊群
将同步与异步非文本任务的准入唤醒改为按任务和全局队首推进,批量续租等待者,避免大量请求同时争抢 advisory lock 和数据库连接。 对 Base64 请求解析、素材解码、上游媒体执行和结果物化增加分层并发限制,复用请求素材并释放重复 Gemini wire 数据;生产 API 默认入口解析并发 16,媒体物化并发 8。 新增 1000 个同步 Gemini 图像编辑请求的模拟上游压力验收,10 MiB 输入和输出下全部成功,Heap 峰值增长约 2.58 GiB,并验证共享上传哈希、单次 attempt 与本地零落盘。 验证:go test ./... -count=1;go vet ./...;gofmt -l 无输出;kubectl kustomize deploy/kubernetes/production;10 MiB Gemini Base64 千任务压力测试通过。
This commit is contained in:
@@ -53,6 +53,60 @@ func TestGeneratedAssetDecisionUploadsInlineImageBase64(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMediaResultMaterializationConcurrencyIsBounded(t *testing.T) {
|
||||
service := New(config.Config{MediaMaterializationConcurrency: 1}, nil, nil)
|
||||
result := map[string]any{
|
||||
"data": []any{map[string]any{
|
||||
"b64_json": base64.StdEncoding.EncodeToString([]byte("inline image")),
|
||||
"mime_type": "image/png",
|
||||
}},
|
||||
}
|
||||
release, err := service.acquireMediaResultSlot(context.Background(), result)
|
||||
if err != nil {
|
||||
t.Fatalf("acquire first media result slot: %v", err)
|
||||
}
|
||||
|
||||
waitCtx, cancel := context.WithTimeout(context.Background(), 25*time.Millisecond)
|
||||
defer cancel()
|
||||
if _, err := service.acquireMediaResultSlot(waitCtx, result); err == nil {
|
||||
t.Fatal("second media result materialization bypassed configured concurrency")
|
||||
}
|
||||
release()
|
||||
|
||||
release, err = service.acquireMediaResultSlot(context.Background(), result)
|
||||
if err != nil {
|
||||
t.Fatalf("acquire released media result slot: %v", err)
|
||||
}
|
||||
release()
|
||||
}
|
||||
|
||||
func TestMediaTaskPreacquiresMaterializationSlotForInlineResultTypes(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, modelType := range []string{
|
||||
"image_generate",
|
||||
"image_edit",
|
||||
"audio_generate",
|
||||
"text_to_speech",
|
||||
"voice_clone",
|
||||
"omni",
|
||||
} {
|
||||
if !mediaTaskNeedsPreUpstreamMaterializationSlot(modelType) {
|
||||
t.Fatalf("%s should preacquire the media materialization slot", modelType)
|
||||
}
|
||||
}
|
||||
for _, modelType := range []string{
|
||||
"text_generate",
|
||||
"text_embedding",
|
||||
"text_rerank",
|
||||
"video_generate",
|
||||
"image_to_video",
|
||||
} {
|
||||
if mediaTaskNeedsPreUpstreamMaterializationSlot(modelType) {
|
||||
t.Fatalf("%s should not hold a media materialization slot across the upstream call", modelType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneratedAssetDecisionUploadsVectorDocumentWithoutChangingType(t *testing.T) {
|
||||
item := map[string]any{
|
||||
"type": "file",
|
||||
|
||||
Reference in New Issue
Block a user