docs: 同步信箱生命周期实现口径——§4 缺口收敛、水位空洞老化、回填事实并入 PROC_STATE
message-lifecycle.md:§4 两个崩溃窗口随"终态与回填意图同体同行"消除(不再是缺口,改为 说明剩余未闭环项是回填跨库单写期间的持续失败);§5.1 补空洞老化规则(自增回滚空位会使 水位永久停摆,超出最大提交时延即判永久并放行,只跳过空洞不越过已存在的行);§5.2 补判据 机制(不依赖独立待办表,R 覆盖退避);§3 表格改回填意图与"到期或已达 NOW − R"。 design.md:§2.1 表以 INBOX_CURSOR 取代 BACKFILL_TODO、PROC_STATE 责任补回填事实; §3.1 收报改为按 ID 区间扫描且不以标记为谓词;§3.3 终态由处理器事务内落库、死信同样可 补写;§6.1 维护作业改为 BackfillService.sweep;§7 补 max-commit-delay/overdue-backfill/ backfill-batch 与 mailbox.processed-value;§8 验证表补"终态未回填不得阻断发现"与"意图随 事务回滚";§9 入口表更新;§10 缺口两则改写为现状与待确认项。 architecture.md:§4 主流程第 1/3/4 步与 §3 存储表同步(水位、回填意图、单事务范围)。 flight-state.md:§2 对象表同步。user-stories.md:US-01/US-09 当前基础与落点改为实现现状、 Q2 口径改为"老化阈值待库方书面承诺"。
This commit is contained in:
@@ -43,7 +43,7 @@ MSG_EVENT PENDING ──→ SENT
|
||||
|
||||
- `PENDING` 与 `FAILED` 是处理中的状态,`FAILED` 继续退避重试并占用 FIFO 队头;`SUCCEEDED / SKIPPED / DEAD` 是终态,到达后队列方可推进。
|
||||
- `DEAD` 与 `FAILED` 不是不可逆:经人工批准,指定错误类别的记录可重新置回 `PENDING` 处理(放行范围见 §9 / design.md §6.1)。重放处理的是当前状态,不恢复历史处理顺序。
|
||||
- 航班变更、待发事件、处理终态与回填待办预登记四类写入位于同一个 PG 事务,一起提交或一起回滚;信箱处理标记写在该事务之后,依赖 `BACKFILL_TODO` 补偿记录最终写入。
|
||||
- 航班变更、待发事件、处理终态与回填意图四类写入位于同一个 PG 事务,一起提交或一起回滚;信箱处理标记写在该事务之后,由与终态同行的回填意图驱动重试与超期补写。
|
||||
|
||||
## 3. 处理阶段
|
||||
|
||||
@@ -53,9 +53,9 @@ MSG_EVENT PENDING ──→ SENT
|
||||
| 取队头 | 最小未完成 `MSG_ID` | 本批处理消息 | 表状态即队列 | 无队头则等待 |
|
||||
| 解码与身份 | 信箱原文 | `DecodedMessage`、`IDENTITY_KEY` | 身份唯一约束 | 报文非法→`DEAD`;处理能力不足→`FAILED` 退避 |
|
||||
| 事务处理 | 当前完整状态 + 报文载荷 | 航班变更、终态、事件、回填待办 | 消息 ID + 业务身份 | 事务整体回滚重试 |
|
||||
| 提交后回填 | 终态消息 | 信箱处理标记 | 标记单调(§11) | 记入 `BACKFILL_TODO` 重试 |
|
||||
| 提交后回填 | 终态消息 | 信箱处理标记 | 标记单调(§11) | 终态事务内登记回填意图;失败退避重试,超期强制补写 |
|
||||
| 投递 | `MSG_EVENT` | 下游确认 | `EVENT_ID` | 退避至 `DEAD`;至少一次 |
|
||||
| 补偿作业 | 回填待办 / 到期批次 | 追平标记 | 待办主键 | 指数退避,独立线程执行 |
|
||||
| 补偿作业 | 到期或已达 `NOW − R` 的终态记录 | 追平标记 | 消息 ID(仅空标生效) | 指数退避,独立线程执行;`R` 覆盖退避 |
|
||||
|
||||
处理器只在持有 `PIPELINE_LOCK` 的事务内写入自有 PG 状态,不操作信箱与 Kafka;全部外部副作用发生在事务提交之后。
|
||||
|
||||
@@ -67,17 +67,17 @@ MSG_EVENT PENDING ──→ SENT
|
||||
|---|---|---|
|
||||
| 已落信、未入队 | 信箱无标记且 PG 无记录 | 重扫补建入队记录 |
|
||||
| 事务执行中 | PG 无该消息终态 | 事务整体回滚,按 `PENDING` 重新处理 |
|
||||
| 事务已提交、标记未写 | `BACKFILL_TODO` 存在待办 | 仅补写标记;业务处理结果保持不变 |
|
||||
| 事务已提交、标记未写 | 终态行仍持有回填意图(`BACKFILL_NEXT_AT` 非空) | 仅补写标记;业务处理结果保持不变 |
|
||||
| 回填待办登记失败(与业务同事务) | 事务未提交 | 同"事务执行中",不构成独立窗口 |
|
||||
| 标记写入中途 | 标记仍为空 | 重新写入;重复写入同一值无副作用 |
|
||||
| 下游已接收、`SENT` 未置 | 事件仍 `PENDING` | 允许重发,下游按事件身份去重 |
|
||||
|
||||
两个缺口在闭环前不能宣称恢复完整(口径与 design.md §10「事务与外部副作用」一致):
|
||||
两个窗口已随"终态与回填意图同体同行"消除(口径与 design.md §10「事务与外部副作用」一致),不再是缺口:
|
||||
|
||||
1. 事务提交后、回填动作开始前的崩溃窗口(提交后回填前崩溃);
|
||||
2. 回填待办二次落账失败(待办落账再次失败)。
|
||||
1. **提交后回填前崩溃**:回填意图与处理终态是同一条记录的同一次写入、同一个事务;重启后扫描按该意图继续补写。
|
||||
2. **回填待办二次落账失败**:不存在第二处落账——意图就在终态行上。
|
||||
|
||||
两项登记于 design.md §10 与 user-stories.md US-09;本表的恢复判定以这两个窗口为前提。
|
||||
仍属未闭环的是回填本身在跨库单写期间的持续失败:由退避重试与 §5.2 的超期期限 `R` 兜底(登记于 design.md §10 与 user-stories.md US-09)。
|
||||
|
||||
## 5. 消费水位、超期补写与历史积压
|
||||
|
||||
@@ -92,6 +92,8 @@ MSG_EVENT PENDING ──→ SENT
|
||||
|
||||
日常执行方式:快路径从 `ID > W` 起按升序有限批次扫描;另按周期对窗口内可能迟到或空洞的行做补偿扫描。需要区分:水位表示"读取进度",与"已处理标记"是两个事实,不能互相替代。
|
||||
|
||||
**空洞老化**:自增回滚等会在 ID 序列中留下永久空位,而 Q2 只承诺 ID 单调、不承诺无空洞。W+1 处的空洞持续超过最大提交时延仍未被补齐时,即判定为永久空洞并放行水位(实现取 `pipeline.max-commit-delay`);放行只跳过空洞本身,不越过任何已存在的行。没有这条规则,水位会永久停摆于第一个空位,其后的行再也不会入队。
|
||||
|
||||
两条扫描路径都按 **ID 区间**取行,不以处理标记为扫描谓词;标记只用于回填与库方清除,不参与消息发现。否则已入队但尚未回填的行会永久占据批次,这正是 US-01 条目 3 与 Q2 要求排除的场景。
|
||||
|
||||
### 5.2 超期标记补写
|
||||
@@ -104,6 +106,7 @@ MSG_EVENT PENDING ──→ SENT
|
||||
- 中间态(`PENDING` / `FAILED`)不适用本规则:处理未完成时不打标,也不允许被清除。
|
||||
- 补写值仅限于库方认可的 legacy 值集(Q7);死信、业务重复等内部原因记录在 `PROC_STATE` 与审计日志,不在信箱新增枚举。
|
||||
- 补写只针对空标记;已有值不回撤、不覆盖,重复执行无副作用。
|
||||
- 判据不依赖独立待办表:回填意图与处理终态同行(§2/§4),扫描条件为「终态 + 未确认标记 + (已到期 或 接收时间早于 `NOW − R`)」——`R` 是覆盖退避的硬期限,保证该条件在有限时间内必然被处理。
|
||||
|
||||
该规则同时保证三件事成立:收报表不被永不回填的记录占满(Q2 中"积压挡批"场景)、§6 的清除边界可以达到、重放期限与信箱保留期具备可核验的下限关系(§9)。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user