init biliup-next
This commit is contained in:
212
docs/state-machine.md
Normal file
212
docs/state-machine.md
Normal file
@ -0,0 +1,212 @@
|
||||
# State Machine
|
||||
|
||||
## Goal
|
||||
|
||||
定义 `biliup-next` 的任务状态机,取代旧系统依赖 flag 文件、日志和目录结构推断状态的方式。
|
||||
|
||||
状态机目标:
|
||||
|
||||
- 让每个任务始终有明确状态
|
||||
- 支持失败重试和人工介入
|
||||
- 让 UI 和 API 可以直接消费状态
|
||||
- 保证步骤顺序和依赖关系清晰
|
||||
|
||||
## State Model
|
||||
|
||||
任务状态分为两层:
|
||||
|
||||
- `task status`:任务整体状态
|
||||
- `step status`:任务中每一步的执行状态
|
||||
|
||||
## Task Status
|
||||
|
||||
### Core Statuses
|
||||
|
||||
- `created`
|
||||
- `ingested`
|
||||
- `transcribed`
|
||||
- `songs_detected`
|
||||
- `split_done`
|
||||
- `published`
|
||||
- `commented`
|
||||
- `collection_synced`
|
||||
- `completed`
|
||||
|
||||
### Failure Statuses
|
||||
|
||||
- `failed_retryable`
|
||||
- `failed_manual`
|
||||
|
||||
### Terminal Statuses
|
||||
|
||||
- `completed`
|
||||
- `cancelled`
|
||||
- `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
|
||||
-> ingested
|
||||
-> transcribed
|
||||
-> songs_detected
|
||||
-> split_done
|
||||
-> published
|
||||
-> commented
|
||||
-> collection_synced
|
||||
-> completed
|
||||
```
|
||||
|
||||
### 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` 成功
|
||||
|
||||
建议:
|
||||
|
||||
- `completed` 表示主链路完成
|
||||
- `collection_synced` 表示所有合集同步完成
|
||||
|
||||
## Retry Strategy
|
||||
|
||||
### Retryable Errors
|
||||
|
||||
适合自动重试:
|
||||
|
||||
- 网络错误
|
||||
- 外部 API 临时失败
|
||||
- 上传频控
|
||||
- 外部命令短时异常
|
||||
|
||||
### Manual Errors
|
||||
|
||||
需要人工介入:
|
||||
|
||||
- 配置缺失
|
||||
- 凭证失效
|
||||
- 文件损坏
|
||||
- provider 不可用
|
||||
- 标题无法匹配完整版 BV
|
||||
|
||||
## Persistence Requirements
|
||||
|
||||
每次状态变更都必须落库:
|
||||
|
||||
- 任务状态
|
||||
- 步骤状态
|
||||
- 开始时间
|
||||
- 结束时间
|
||||
- 错误码
|
||||
- 错误信息
|
||||
- 重试次数
|
||||
|
||||
## UI Expectations
|
||||
|
||||
UI 至少需要直接展示:
|
||||
|
||||
- 当前任务状态
|
||||
- 当前正在运行的步骤
|
||||
- 最近失败步骤
|
||||
- 重试次数
|
||||
- 是否需要人工介入
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- 不追求一个任务多个步骤完全并发执行
|
||||
- 不允许继续依赖 flag 文件作为权威状态来源
|
||||
Reference in New Issue
Block a user