feat(render): 优化模板渲染状态管理逻辑

- 引入 TaskRenderJobMappingMapper 和 TaskRenderJobMappingEntity 处理渲染作业映射关系
- 重构 FaceStatusManager 中的模板渲染状态查询逻辑,基于任务渲染作业映射确定准确状态
- 在 TaskTaskServiceImpl 中完善视频复用场景下的状态标记机制
- 新增 RenderJobPollingService 中的模板渲染状态更新功能,在预览就绪时同步更新缓存状态
- 添加渲染失败时的状态重置机制,确保状态一致性
- 实现基于任务ID查询关联信息并更新模板渲染状态的通用方法
This commit is contained in:
2026-02-06 21:07:55 +08:00
parent 092c99d25d
commit a79cbe4f84
3 changed files with 49 additions and 8 deletions

View File

@@ -6,7 +6,9 @@ import com.ycwl.basic.enums.FaceCutStatus;
import com.ycwl.basic.enums.FacePieceUpdateStatus; import com.ycwl.basic.enums.FacePieceUpdateStatus;
import com.ycwl.basic.enums.TemplateRenderStatus; import com.ycwl.basic.enums.TemplateRenderStatus;
import com.ycwl.basic.mapper.TaskMapper; import com.ycwl.basic.mapper.TaskMapper;
import com.ycwl.basic.mapper.task.TaskRenderJobMappingMapper;
import com.ycwl.basic.model.pc.task.entity.TaskEntity; import com.ycwl.basic.model.pc.task.entity.TaskEntity;
import com.ycwl.basic.model.task.entity.TaskRenderJobMappingEntity;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -51,6 +53,8 @@ public class FaceStatusManager {
@Autowired @Autowired
private TaskMapper taskMapper; private TaskMapper taskMapper;
@Autowired
private TaskRenderJobMappingMapper taskRenderJobMappingMapper;
public FaceStatusManager() { public FaceStatusManager() {
// 初始化三个独立的缓存实例 // 初始化三个独立的缓存实例
@@ -257,19 +261,26 @@ public class FaceStatusManager {
Integer code = templateRenderCache.getIfPresent(faceId + ":" + templateId); Integer code = templateRenderCache.getIfPresent(faceId + ":" + templateId);
if (code == null) { if (code == null) {
log.debug("模板渲染状态缓存不存在: faceId={}, templateId={}", faceId, templateId); log.debug("模板渲染状态缓存不存在: faceId={}, templateId={}", faceId, templateId);
// 查询数据库 // 查询数据库:通过 task_render_job_mapping 确定渲染状态
TaskEntity task = taskMapper.listLastFaceTemplateTask(faceId, templateId); TaskEntity task = taskMapper.listLastFaceTemplateTask(faceId, templateId);
if (task == null) { if (task == null) {
setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.NONE); setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.NONE);
return TemplateRenderStatus.NONE; return TemplateRenderStatus.NONE;
} }
if (Integer.valueOf(2).equals(task.getStatus())) { TaskRenderJobMappingEntity mapping = taskRenderJobMappingMapper.selectByTaskId(task.getId());
setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERING); if (mapping == null) {
setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.NONE);
return TemplateRenderStatus.NONE;
} }
if (Integer.valueOf(1).equals(task.getStatus())) { TemplateRenderStatus status = switch (mapping.getRenderStatus()) {
setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERED); case TaskRenderJobMappingEntity.STATUS_PENDING -> TemplateRenderStatus.RENDERING;
} case TaskRenderJobMappingEntity.STATUS_PREVIEW_READY,
return TemplateRenderStatus.NONE; TaskRenderJobMappingEntity.STATUS_MP4_COMPOSING,
TaskRenderJobMappingEntity.STATUS_COMPLETED -> TemplateRenderStatus.RENDERED;
default -> TemplateRenderStatus.NONE; // FAILED 等异常状态
};
setTemplateRenderStatus(faceId, templateId, status);
return status;
} }
return TemplateRenderStatus.fromCode(code); return TemplateRenderStatus.fromCode(code);
} }

View File

@@ -1,5 +1,7 @@
package com.ycwl.basic.service.task; package com.ycwl.basic.service.task;
import com.ycwl.basic.biz.FaceStatusManager;
import com.ycwl.basic.enums.TemplateRenderStatus;
import com.ycwl.basic.integration.render.dto.job.FinalizeMP4Response; import com.ycwl.basic.integration.render.dto.job.FinalizeMP4Response;
import com.ycwl.basic.integration.render.dto.job.JobStatusResponse; import com.ycwl.basic.integration.render.dto.job.JobStatusResponse;
import com.ycwl.basic.integration.render.service.RenderJobIntegrationService; import com.ycwl.basic.integration.render.service.RenderJobIntegrationService;
@@ -49,6 +51,7 @@ public class RenderJobPollingService {
private final VideoTaskRepository videoTaskRepository; private final VideoTaskRepository videoTaskRepository;
private final VideoRepository videoRepository; private final VideoRepository videoRepository;
private final MemberRelationRepository memberRelationRepository; private final MemberRelationRepository memberRelationRepository;
private final FaceStatusManager faceStatusManager;
/** /**
* 定时轮询间隔:2秒 * 定时轮询间隔:2秒
@@ -179,6 +182,9 @@ public class RenderJobPollingService {
updateMappingStatus(mapping.getId(), TaskRenderJobMappingEntity.STATUS_PREVIEW_READY, updateMappingStatus(mapping.getId(), TaskRenderJobMappingEntity.STATUS_PREVIEW_READY,
publishedCount, segmentCount, playUrl, null); publishedCount, segmentCount, playUrl, null);
// 更新模板渲染状态缓存为已渲染(预览就绪即视为渲染成功)
updateTemplateRenderStatus(taskId, TemplateRenderStatus.RENDERED);
// 更新task的videoUrl为预览地址 // 更新task的videoUrl为预览地址
if (StringUtils.isNotBlank(playUrl)) { if (StringUtils.isNotBlank(playUrl)) {
TaskEntity task = new TaskEntity(); TaskEntity task = new TaskEntity();
@@ -307,6 +313,26 @@ public class RenderJobPollingService {
errorMessage, errorMessage,
new Date() new Date()
); );
// 渲染失败,重置模板渲染状态
updateTemplateRenderStatus(mapping.getTaskId(), TemplateRenderStatus.NONE);
}
/**
* 更新模板渲染状态缓存
* 根据 taskId 查询关联的 faceId 和 templateId,更新 FaceStatusManager 中的渲染状态
*/
private void updateTemplateRenderStatus(Long taskId, TemplateRenderStatus status) {
try {
var taskInfo = taskMapper.getById(taskId);
if (taskInfo != null && taskInfo.getFaceId() != null && taskInfo.getTemplateId() != null) {
faceStatusManager.setTemplateRenderStatus(taskInfo.getFaceId(), taskInfo.getTemplateId(), status);
log.info("[渲染轮询] 已更新模板渲染状态: taskId={}, faceId={}, templateId={}, status={}",
taskId, taskInfo.getFaceId(), taskInfo.getTemplateId(), status.getDescription());
}
} catch (Exception e) {
log.warn("[渲染轮询] 更新模板渲染状态缓存失败: taskId={}, error={}", taskId, e.getMessage());
}
} }
/** /**

View File

@@ -436,6 +436,7 @@ public class TaskTaskServiceImpl implements TaskService {
if (video != null) { if (video != null) {
log.info("自动创建任务:跳过(auto_replace_vlog=false), faceId:{}, templateId:{}, existingTaskId:{}, videoId:{}", log.info("自动创建任务:跳过(auto_replace_vlog=false), faceId:{}, templateId:{}, existingTaskId:{}, videoId:{}",
faceId, templateId, taskEntity.getId(), video.getId()); faceId, templateId, taskEntity.getId(), video.getId());
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERED);
return; return;
} }
} }
@@ -492,7 +493,10 @@ public class TaskTaskServiceImpl implements TaskService {
} }
videoMapper.addRelation(memberVideoEntity); videoMapper.addRelation(memberVideoEntity);
memberRelationRepository.clearVCacheByFace(faceId); memberRelationRepository.clearVCacheByFace(faceId);
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERED); // 仅当复用已有视频时立即标记为已渲染,新任务由 RenderJobPollingService 在 PREVIEW_READY 时更新
if (memberVideoEntity.getVideoId() != null) {
faceStatusManager.setTemplateRenderStatus(faceId, templateId, TemplateRenderStatus.RENDERED);
}
faceStatusManager.markNoNewPieces(faceId, templateId); faceStatusManager.markNoNewPieces(faceId, templateId);
}; };
VideoPieceGetter.addTask(task); VideoPieceGetter.addTask(task);