fix: 保持产物收尾幂等并保护批量成品完整性

This commit is contained in:
2026-09-11 16:12:32 +08:00
parent f3faad0391
commit 3a612919f7
8 changed files with 293 additions and 43 deletions
+11 -6
View File
@@ -48,6 +48,7 @@ from wov_app.config import BATCH_INTERVAL_SECONDS, STORAGE_DIR
from wov_app.db import Database
from wov_app.logging import get_logger
from wov_app.scheduler import WorkflowScheduler
from wov_app.storage import atomic_copy
from wov_sdk.models import WorkflowDefinition
# 批量引擎运行日志:任务进度、视频逐个处理与暂停/续跑等状态变化。
@@ -531,18 +532,22 @@ class BatchWorker:
"已有字幕"规则跳过该视频。同名目标直接覆盖:可能是上一次运行/旧工作流
留下的旧内容,应以本次产物为准。
"""
placed: list[str] = []
video.parent.mkdir(parents=True, exist_ok=True)
# 先校验全部必需输出,缺文件时不覆盖任何视频旁成品,更不能继续清理。
products: list[tuple[Path, Path]] = []
for alias in definition.final_outputs:
artifact = self.db.get_artifact(run_id, alias)
if artifact is None:
continue
raise ValueError(f"missing final artifact: {alias}")
source = Path(artifact["uri"])
if not source.is_file():
continue
raise ValueError(f"missing final artifact file: {alias} ({source})")
target = video.parent / _sidecar_product_name(video, source)
# 目标名稳定 → 直接覆盖写入,避免旧同名产物被"大小一致复用"误保留。
shutil.copy2(source, target)
products.append((source, target))
placed: list[str] = []
for source, target in products:
# 稳定目标名 + 原子替换:复制失败保留旧成品,异常交调用方记录 FAILED。
# 多文件中途失败仍保留完整工作空间,下次可以幂等地重新放置。
atomic_copy(source, target)
placed.append(target.name)
return placed