perf(storage): 拦截任务二进制并本地暂存结果
原因:任务标准结果中的 Base64、Data URI 和 Buffer 会进入 PostgreSQL JSON,导致 TOAST 与备份体积快速增长。 影响:新增统一 JSON 持久化关口;upload_none 将二进制原子写入本地结果目录,数据库仅保存带 SHA-256 的有界占位符;任务详情、同步响应、异步查询和兼容协议按需校验恢复。补充 24 小时清理、容量上限、历史小批量治理命令及管理端说明。 风险:本地结果超过 TTL、丢失或损坏时分别返回明确的 410/500;空间不足时返回 503 且不重试上游。未自动执行历史治理。 验证:三种真实图片模型同步/异步与幂等重放通过;Go vet/全量测试、前端 111 测试、lint/typecheck/build、OpenAPI、迁移安全、govulncheck、依赖审计、手工发布测试及 Linux amd64 构建通过。
This commit is contained in:
@@ -56,12 +56,19 @@ func (s *Server) createVolcesContentsGenerationTask(w http.ResponseWriter, r *ht
|
||||
// @Param taskID path string true "任务 ID"
|
||||
// @Success 200 {object} VolcesContentsGenerationTaskResponse
|
||||
// @Failure 404 {object} VolcesErrorEnvelope
|
||||
// @Failure 410 {object} VolcesErrorEnvelope
|
||||
// @Router /api/v1/contents/generations/tasks/{taskID} [get]
|
||||
func (s *Server) getVolcesContentsGenerationTask(w http.ResponseWriter, r *http.Request) {
|
||||
task, ok := s.volcesCompatibleTaskForUser(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var err error
|
||||
task, err = s.hydrateTaskResult(r.Context(), task)
|
||||
if err != nil {
|
||||
writeVolcesError(w, statusFromRunError(err), err.Error(), clients.ErrorCode(err))
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, volcesCompatibleTask(task))
|
||||
}
|
||||
|
||||
@@ -178,6 +185,7 @@ func (s *Server) createLegacyVolcesVideoGeneration(w http.ResponseWriter, r *htt
|
||||
// @Param taskID path string true "任务 ID"
|
||||
// @Success 200 {object} EasyAIGeneratedResponse
|
||||
// @Failure 404 {object} EasyAIGeneratedResponse
|
||||
// @Failure 410 {object} EasyAIGeneratedResponse
|
||||
// @Router /api/v1/ai/result/{taskID} [get]
|
||||
func (s *Server) getEasyAITaskResult(w http.ResponseWriter, r *http.Request) {
|
||||
user, ok := auth.UserFromContext(r.Context())
|
||||
@@ -199,6 +207,11 @@ func (s *Server) getEasyAITaskResult(w http.ResponseWriter, r *http.Request) {
|
||||
writeEasyAIAsyncError(w, http.StatusNotFound, "task not found", nil, "not_found")
|
||||
return
|
||||
}
|
||||
task, err = s.hydrateTaskResult(r.Context(), task)
|
||||
if err != nil {
|
||||
writeEasyAIAsyncError(w, statusFromRunError(err), err.Error(), nil, clients.ErrorCode(err))
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, easyAITaskResultResponse(task))
|
||||
}
|
||||
|
||||
@@ -408,6 +421,8 @@ func writeVolcesCompatibleTaskError(w http.ResponseWriter, err error) {
|
||||
status = clientErr.StatusCode
|
||||
} else if errors.As(err, &clientErr) {
|
||||
status = http.StatusBadRequest
|
||||
} else if errors.Is(err, store.ErrTaskRequestBinaryNotMaterialized) {
|
||||
status = http.StatusBadRequest
|
||||
}
|
||||
if wire := clients.ErrorWireResponse(err); wireResponseMatches(wire, clients.ProtocolVolcesContents) {
|
||||
writeWireResponse(w, wire)
|
||||
|
||||
Reference in New Issue
Block a user