# State Machine ## Goal 定义 `biliup-next` 当前实现使用的任务状态机,并明确数据库状态与工作区 flag 的职责边界。 状态机目标: - 让每个任务始终有明确状态 - 支持失败重试和人工介入 - 让 UI 和 API 可以直接消费状态 - 保证步骤顺序和依赖关系清晰 ## State Model 任务状态分为两层: - `task status`:任务整体状态 - `step status`:任务中每一步的执行状态 ## Task Status ### Core Statuses - `created` - `running` - `transcribed` - `songs_detected` - `split_done` - `published` - `commented` - `collection_synced` ### Failure Statuses - `failed_retryable` - `failed_manual` ### Terminal Statuses - `collection_synced` - `failed_manual` ## Step Status 每个步骤都独立维护自己的状态。 - `pending` - `running` - `succeeded` - `failed_retryable` - `failed_manual` - `skipped` ## Step Definitions ### ingest 负责: - 接收输入视频 - 基础校验 - 创建任务记录 ### transcribe 负责: - 生成字幕 - 记录字幕产物 ### song_detect 负责: - 识别歌曲列表 - 生成 `songs.json` 和 `songs.txt` ### split 负责: - 根据歌单切割视频 - 生成切片产物 ### publish 负责: - 上传纯享版视频 - 记录 `aid/bvid` ### comment 负责: - 发布评论 - 置顶评论 ### collection_a 负责: - 将完整版视频加入合集 A ### collection_b 负责: - 将纯享版视频加入合集 B ## State Transition Rules ### Task-Level ```text created -> running -> transcribed -> running -> songs_detected -> running -> split_done -> running -> published -> running -> commented -> running -> collection_synced ``` 说明: - `running` 是任务级瞬时状态,表示当前已有某个 step 被 claim 并正在执行。 - 当该 step 成功结束后,task 会回到对应业务状态,例如 `transcribed`、`split_done`、`published`。 - 当前实现中未使用 `ingested`、`completed`、`cancelled` 作为 task 状态。 ### Failure Transition 任何步骤失败后: - 若允许自动重试:任务进入 `failed_retryable` - 若必须人工介入:任务进入 `failed_manual` 重试成功后: - 任务回到该步骤成功后的下一个合法状态 ## Dependency Rules - `transcribe` 必须依赖 `ingest` - `song_detect` 必须依赖 `transcribe` - `split` 必须依赖 `song_detect` - `publish` 必须依赖 `split` - `comment` 必须依赖 `publish` - `collection_b` 必须依赖 `publish` - `collection_a` 通常依赖外部完整版 BV,可独立于 `publish` ## Special Case: Collection A 合集 A 的数据来源与主上传链路不同。 因此: - `collection_a` 不应阻塞主任务完成 - `collection_a` 可作为独立步骤存在 - 任务整体完成不必强依赖 `collection_a` 成功 当前实现: - `collection_synced` 表示当前任务已经完成既定收尾流程。 - `collection_a` / `collection_b` 仍作为独立 step 存在,但系统暂未额外引入 `completed` 状态。 ## Retry Strategy ### Retryable Errors 适合自动重试: - 网络错误 - 外部 API 临时失败 - 上传频控 - 外部命令短时异常 ### Manual Errors 需要人工介入: - 配置缺失 - 凭证失效 - 文件损坏 - provider 不可用 - 标题无法匹配完整版 BV ## Persistence Requirements 每次状态变更都必须落库: - 任务状态 - 步骤状态 - 开始时间 - 结束时间 - 错误码 - 错误信息 - 重试次数 ## Flags And Files 工作区中的 flag 文件仍然存在,但它们不是 task 主状态的权威来源。 当前职责划分: - 数据库: - task 状态 - step 状态 - 重试信息 - 结构化上下文 - 工作区文件与 flag: - 外部副作用是否已执行 - 产物是否已落地 - 评论/合集等交付标记 换句话说: - “任务现在处于什么状态”以数据库为准。 - “某个外部动作是否已经做过”可以由工作区 flag 辅助表达。 ## UI Expectations UI 至少需要直接展示: - 当前任务状态 - 当前正在运行的步骤 - 最近失败步骤 - 重试次数 - 是否需要人工介入 ## Non-Goals - 不追求一个任务多个步骤完全并发执行 - 不把工作区 flag 文件当作 task 主状态来源