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:
+15
-13
@@ -17,12 +17,12 @@
|
||||
|
||||
| 记录 | 用途 | 关键约束 |
|
||||
|---|---|---|
|
||||
| `PROC_STATE` | 入站消息的处理状态、身份、重试次数和错误原因 | `MSG_ID = CMINMSGS_ID` 主键防止重复入队;`IDENTITY_KEY` 唯一约束防止业务重复;按最小未完成消息 ID 取队头。 |
|
||||
| `PROC_STATE` | 入站消息的处理状态、身份、重试次数、错误原因与回填事实 | `MSG_ID = CMINMSGS_ID` 主键防止重复入队;`IDENTITY_KEY` 唯一约束防止业务重复;按最小未完成消息 ID 取队头;`RECEIVED_AT` 与 `BACKFILL_*` 承载 §5.2 超期判据与回填重试。 |
|
||||
| `MSG_EVENT` | 等待投递的事件(outbox) | `EVENT_ID` 决定投递顺序;`TARGET` 区分 `KAFKA:msg` / `KAFKA:schd`;`PARTITION_KEY` 恒为 `FLID`;`EVENT_TYPE` 区分 UPSERT 与 TOMBSTONE。 |
|
||||
| `REQ_TRACK` | 上游请求及应答关联 | 保存请求类型、覆盖运营日、发送方、出站信箱 ID 与发送/完成时间;同类只允许一个开放请求。登记、超时与应答匹配尚未实现(§10)。 |
|
||||
| `REF_MASTER` | 静态参考数据(目标表) | `(RTYPE, RKEY)` 唯一;尚未建表,客户端与刷新流程见 user-stories.md US-13/US-14(US-14 两类映射的存储落点未定)。 |
|
||||
| `FLIGHT_SCHD` | 航班标量及单值异常字段 | `FLID` 主键;`OPERATION_DAY` 一经确定不可变;版本与最近消息 ID 用于追踪。变长资源集合存于 9 张明细表,规则见 [flight-state.md](flight-state.md) §2,不在此重复。 |
|
||||
| `BACKFILL_TODO` | 共享信箱回填重试 | 回填意图与业务终态同事务预登记,提交后回填成功即删除;待办再次落账失败的崩溃窗口仍在(§10)。 |
|
||||
| `INBOX_CURSOR` | 共享信箱消费水位 `W` | 单行游标;只随新 ID 成功入队推进,遇空洞即停,空洞超期判定为永久([message-lifecycle.md](message-lifecycle.md) §5.1)。 |
|
||||
| `PROC_STATE_HST` | 终态处理记录的归档目标 | 尚未建表;不得改写为共享库历史表。 |
|
||||
|
||||
字段与索引定义以 `src/main/resources/db/migration/V1__flight_state_baseline.sql` 为准;Oracle 11g 的迁移形态见 `src/main/resources/db/migration/oracle11g/`(占位,未接入任何 Flyway 配置)。报文原文仍从共享信箱读取,因此必须协调原文保留期,不能在消息尚需处理或重放时提前清理;生命周期、回填与清除契约的唯一定义见 [message-lifecycle.md](message-lifecycle.md)。
|
||||
@@ -69,9 +69,9 @@ SNDR | TYPE | STYP | SEQN
|
||||
|
||||
### 3.1 收报
|
||||
|
||||
`InboxPoller` 默认每秒按 ID 升序、有限批次(`claim-batch`,默认 50)读取 `DATE_PROCESSED IS NULL` 的信箱记录,经 `InboxEnqueue` 在自有 PG 建立 `PENDING`;重复扫描幂等,入队失败留待下一轮。收报层不解析业务载荷,也不回填已处理标记。
|
||||
`InboxPoller` 默认每秒按 ID 升序、有限批次(`claim-batch`,默认 50)读取水位之后的信箱记录(`ID > W`,**不以处理标记为谓词**),在自有 PG 建立 `PENDING` 并把水位推进到连续上界;入队与水位推进在同一 PG 事务内提交,重复扫描幂等、中断后重扫补建。收报层不解析业务载荷,也不回填已处理标记。
|
||||
|
||||
水位的定义(连续上界、遇空洞即停)、扫描谓词与补偿窗口唯一见 [message-lifecycle.md](message-lifecycle.md) §5.1;水位不是已处理标记,其有效性以 Q2 的 ID 单调承诺为前提。快路径水位与受控补扫仍是目标形态,当前按 `afterId=0` 每轮全量扫描(§10),迟提交与空洞场景的顺序保证在启用前必须验证。
|
||||
水位 W 与扫描谓词的完整口径(连续上界、遇空洞即停、空洞老化)唯一见 [message-lifecycle.md](message-lifecycle.md) §5.1;水位不是已处理标记,其有效性以 Q2 的 ID 单调承诺为前提。空洞老化阈值取 `pipeline.max-commit-delay`。
|
||||
|
||||
兼容 HTTP 入口执行“写入共享信箱 → PG 入队”。两步不在同一事务中:信箱成功而 PG 失败时,原文不能丢失,由轮询补建;客户端失败重试可能再次写信箱,业务身份去重仍然必需。
|
||||
|
||||
@@ -100,8 +100,8 @@ SNDR | TYPE | STYP | SEQN
|
||||
|
||||
- 原文缺失归为 `MALFORMED`;读取异常不能伪装成“缺失”,应进入基础设施重试。
|
||||
- 忽略规则(`LDM / REGN / RSTA / EROR` → `SKIPPED`)尚未实现(§10);不能因类型未覆盖就把合法忽略报文当非法报文处理。
|
||||
- 航班变更、待发事件、处理终态与回填待办在同一 PG 事务原子提交;跨存储双写窗口已根除。
|
||||
- 终态回填发生在提交后:成功、业务重复与协议拒绝包持有可用 META 并回填;缺 META 或解码失败的死信不在常规回填范围,按超期补写规则处理([message-lifecycle.md](message-lifecycle.md) §5.2;US-09/Q7)。`PENDING / FAILED` 禁止回填;影子环境禁写。
|
||||
- 航班变更、待发事件、处理终态与回填意图在同一 PG 事务原子提交(终态由处理器在自己的事务内落库,`MessageProcessor` 不再单独补写终态);跨存储双写窗口已根除。
|
||||
- 终态提交后立即尝试一次回填,失败由回填扫描按退避重试,抵达超期期限 R 时按 [message-lifecycle.md](message-lifecycle.md) §5.2 强制补写(US-09/Q7)。回填只需消息 ID,因此缺 META 或解码失败的死信同样可补写。`PENDING / FAILED` 禁止回填;影子环境禁写。
|
||||
|
||||
## 4. 日计划快照与请求匹配
|
||||
|
||||
@@ -163,7 +163,7 @@ REGISTERED → SENT → WAITING → DONE
|
||||
|
||||
`ReplayService` 只允许 `CODEC_ERROR / UNSUPPORTED / INFRA / EXHAUSTED` 从 `FAILED / DEAD` 回到 `PENDING`,重置次数与下次执行时间,保留身份与错误审计。它按错误类整批重放,尚无按记录预检、操作审计与管理入口(US-10)。旧消息进入终态后后续消息可能已执行,**重新入队不等于恢复历史顺序**;人工重放前必须评估状态覆盖和版本保护,不能直接批量重放到生产。
|
||||
|
||||
**维护作业**:`JobRunner` 用独立 daemon 线程每 30 秒触发 `BackfillSweepJob`(回填补偿扫描,指数退避 30 秒起步、封顶 15 分钟),每天机场时区 03:30 后触发一次 `HistorySweepJob`(§6.2)。作业不再经 `PUMP_JOB` 队列插队,不参与消息 FIFO,也不使到期消息饥饿。作业与回填通道的生命周期口径见 [message-lifecycle.md](message-lifecycle.md) §3/§4。
|
||||
**维护作业**:`JobRunner` 用独立 daemon 线程每 30 秒触发 `BackfillService.sweep`(回填补写扫描,指数退避 30 秒起步、封顶 15 分钟),每天机场时区 03:30 后触发一次 `HistorySweepJob`(§6.2)。回填意图在终态事务内登记在 `PROC_STATE`(`BACKFILL_NEXT_AT/ATTEMPTS/ERROR`),不再有独立待办表。作业不再经 `PUMP_JOB` 队列插队,不参与消息 FIFO,也不使到期消息饥饿。作业与回填通道的生命周期口径见 [message-lifecycle.md](message-lifecycle.md) §3/§4。
|
||||
|
||||
### 6.2 历史清理与归档
|
||||
|
||||
@@ -183,6 +183,8 @@ REGISTERED → SENT → WAITING → DONE
|
||||
|
||||
- `pipeline.autostart` 与 `msgx.stubs`:分别控制管道启动与内存适配器;生产禁止 stub,默认不自动启动。
|
||||
- `pipeline.poll-interval / claim-batch / max-attempts / backoff / head-deadline`:控制轮询节奏、批次、重试上限、退避与队头滞留;这些参数不能改变 FIFO。
|
||||
- `pipeline.max-commit-delay / overdue-backfill / backfill-batch`:空洞老化阈值(Q2 最大提交时延)、超期补写期限 R(Q6)与回填扫描批量;R 与老化阈值都不能为提速而下调。
|
||||
- `mailbox.processed-value`:写回共享信箱的处理标记值,仅限库方认可的 legacy 值集(Q7)。
|
||||
- `schd.flush-period / flush-limit`:控制状态通知的聚合延迟与批量大小。
|
||||
- `identity.include-day-boundary`:影响去重语义,不能作为普通调优项切换。
|
||||
- `mailbox.shared-mysql.enabled` 与 `history.history-store-enabled`:分别门控真实信箱与历史存储接线,默认关闭。
|
||||
@@ -195,12 +197,12 @@ REGISTERED → SENT → WAITING → DONE
|
||||
|
||||
| 场景 | 必须验证的结果 |
|
||||
|---|---|
|
||||
| 重复扫描、入队中断、较小 ID 迟到 | 不重复入队、不丢记录、不让后续消息越序。 |
|
||||
| 重复扫描、入队中断、较小 ID 迟到 | 不重复入队、不丢记录、不让后续消息越序;终态而未回填的行不得阻断后续消息发现。 |
|
||||
| 队头失败、退避及作业竞争 | 消息不越队;到期后恢复;作业不使消息无限饥饿。 |
|
||||
| 同身份多条记录、失败后重试、归档后重复 | 只产生一次有效业务处理,不把自身重试判为重复。 |
|
||||
| PG 事务失败、快照重复或迟到 | 整体回滚重试、不重复推进版本、不回退状态、不误删增量航班。 |
|
||||
| 整包协议拒绝(运营日冲突、声明数不符) | 整包不落地、整体回滚,既有状态与版本不变,消息终态为 `DEAD(PROTOCOL)`。 |
|
||||
| PG 提交失败、信箱回填失败 | 事件与处理结果一起回滚;已提交结果只由回填待办补偿,不重放业务。 |
|
||||
| PG 提交失败、信箱回填失败 | 事件、处理终态与回填意图一起回滚;已提交结果只补写标记,不重放业务;中间态永不补写。 |
|
||||
| 投递确认丢失、批次失败、次数耗尽 | 允许可识别的重发、保持目标顺序、整批退避并保留死信。 |
|
||||
| 请求超时、无匹配 RESP、时间单位不一致 | 不误用迟到应答,不提前完成请求。 |
|
||||
| stub 误配置、重复实例、停机中断 | 生产拒绝不安全启动,工作线程能正确退出。 |
|
||||
@@ -213,11 +215,11 @@ REGISTERED → SENT → WAITING → DONE
|
||||
|
||||
| 关注点 | 主要入口 |
|
||||
|---|---|
|
||||
| 收报与兼容接口 | `ingress/InboxPoller.kt`、`InboxEnqueue.kt`、`InboxService.kt`、`InboxController.kt` |
|
||||
| 收报与兼容接口 | `ingress/InboxPoller.kt`、`InboxService.kt`、`InboxController.kt` |
|
||||
| 解码 | `codec/JacksonXmlCodec.kt`、`SisWireMapper.kt`、`SisMessageBody.kt` |
|
||||
| 调度与处理 | `processing/Pump.kt`(含 `MessageProcessor`)、`DynamicProcessors.kt`(FLOP/FDEL/ADFT)、`Identity.kt` |
|
||||
| 日计划 | `processing/ScheduleProcessor.kt`;请求协调尚无实现(`REQ_TRACK` 见 `infra/persistence/`) |
|
||||
| 投递与作业 | `delivery/Dispatcher.kt`、`jobs/JobRunner.kt`、`BackfillSweepJob.kt`、`HistorySweepJob.kt` |
|
||||
| 回填与投递作业 | `processing/BackfillService.kt`、`jobs/JobRunner.kt`、`HistorySweepJob.kt`、`delivery/Dispatcher.kt` |
|
||||
| 持久化与恢复 | `infra/persistence/`、`infra/retry/`(`ProcFailure` / `ReplayService` / `FailureScheduler`) |
|
||||
| 启停与配置 | `PipelineLifecycle.kt`、`config/PipelineProps.kt`、`config/HistoryProps.kt` |
|
||||
|
||||
@@ -225,8 +227,8 @@ REGISTERED → SENT → WAITING → DONE
|
||||
|
||||
以下缺口直接影响上述设计是否成立,不能以类或接口已存在作为完成依据:
|
||||
|
||||
- **事务与外部副作用**:状态、事件、终态与回填待办同 PG 事务已实现,回填失败落 `BACKFILL_TODO` 并由 `BackfillSweepJob` 到期重试。剩余缺口在“提交后回填前崩溃”与“待办落账再次失败”两个窗口,不能认定补偿最终必达;两个窗口的恢复判定见 [message-lifecycle.md](message-lifecycle.md) §4。
|
||||
- **收报与调度**:轮询仍从 `afterId=0` 每轮全量扫描,持久水位与受控补扫未完成;较小 ID 迟提交与空洞场景的顺序保证未验证。滞留判据使用 `updatedAt` 与直取系统时间,未基于稳定起始时刻。
|
||||
- **事务与外部副作用**:状态、事件、处理终态与回填意图同 PG 事务提交;回填意图落在 `PROC_STATE`(`BACKFILL_AT/NEXT_AT/ATTEMPTS/ERROR`),`BACKFILL_TODO` 已随 V2 迁移下线,[message-lifecycle.md](message-lifecycle.md) §4 的两个崩溃窗口(提交后回填前崩溃、待办二次落账失败)不再存在。回填本身仍是跨库单写,失败按退避重试并由超期期限 R 兜底;R 的取值待 Q6 确认。
|
||||
- **收报与调度**:水位 W 落库并与入队同事务推进,遇空洞即停、空洞超过 `max-commit-delay` 判定为永久(Q2 未书面确认前该阈值是假定值);较小 ID 迟提交与空洞场景的顺序保证仍待与库方联合验证。滞留判据仍使用 `updatedAt` 与系统时钟(已改经可注入 `Clock`),未基于稳定起始时刻(Q6)。
|
||||
- **快照与业务能力**:DNLD/RESP/ADFT 与 FLOP/FDEL 处理器、整包校验与跨运营日整包拒绝均已接入;但 RESP 应答守卫与出站请求未实现,忽略规则(US-04)未实现,29 类 FLOP 与参考应答的逐类矩阵未补全,ADFT 缺失字段与 `FLID` 重用语义待上游确认。
|
||||
- **航班读写**:唯一写入口与权威读已落地;ROUT/ERUT 联合主键、空值/未知属性保真、事件在事务内只算一次、逐航班多次查询仍待修正(见 flight-state.md §6)。`/all/flights` 尚未实现。
|
||||
- **请求、参考数据与归档**:`REQ_TRACK` 表与仓储已建,但无运行时协调与 `COUTMSGS` 出站适配;`REF_MASTER` 未建表;`PROC_STATE_HST` 未建表。航班历史清理脚手架已实现,历史存储未接通时删 0 条。
|
||||
|
||||
Reference in New Issue
Block a user