Commit Graph
13 Commits
Author SHA1 Message Date
windyboy 9bf879ff76 feat(metrics): 投递失败与死信可观测指标,修 flushSchd 首次失败原因丢失(ACM2-98)
- PipelineCounters 按 target 累计发送失败;Dispatcher.retryOrDead 记账(OPS-2)
- 新增 deadByTarget 查询与 DeliveryDeadSnapshotProvider(TTL 缓存),死信存量按 target 暴露
- /metrics 注册 send_failures.total{target} 与 dead{target},登记进 reference.md「指标与健康」
- flushSchd 失败改记真实异常原因,不再退回固定 send-failed
2026-09-21 12:40:53 +08:00
windyboy df087c7933 fix(delivery): msg 队头失败或退避只暂停同 FLID,不阻塞其他航班(ACM2-95)
- drainKafkaMsg 按分区键维护本轮暂停集:队头失败/退避未到期仅停该 FLID(D2)
- 同一 FLID 内仍严格按 EVENT_ID 保序不越队
- 补三条用例:失败仅停同 FLID、退避未到期仅停同 FLID、同 FLID 跨轮保序(TestClocks 无 sleep)
2026-09-21 12:26:09 +08:00
windyboy cedd859bdf docs(acm2-74): consolidate design documentation 2026-09-13 20:31:13 +08:00
windyboy fc744d0cfd feat(acm2): 闭合 G-KAFKA-D3 / G-IGNORE / G-EVENT-RETENTION 三个缺口
- G-KAFKA-D3:max-in-flight 默认收敛到 1,KafkaD3Check 启动自检钉住三项联合满足 D3
- G-IGNORE:IgnoreRules 在身份绑定后精确匹配 TYPE 字段,命中写 SKIPPED + 回填意图
- G-EVENT-RETENTION:V10 迁移加 SENT_AT 列,投递原子写,EventCleanupJob 有界清理过期 SENT 行
2026-09-13 15:48:16 +08:00
windyboy d21555091f fix(delivery): upsert latest schedule event
KAFKA:schd 收敛为每 FLID 单行:V9 先按 (STATE_VERSION DESC, EVENT_ID DESC) 收敛存量再建部分唯一索引 uq_schd_event;写入走带谓词的单行 upsert(只进不退、同版本 tombstone 优先、接受新代次即换 EVENT_ID 并重置 PENDING/清旧错误);读取不再 DISTINCT ON;成功确认改按 (EVENT_ID, STATE_VERSION, PENDING) 条件更新,删除 Dispatcher superseded 清理循环。msg 路径不变。

验证:全量 ./gradlew test 129 tests / 0 fail(新增 3 个用例:单行只进不退、同版本 tombstone 不可复活、发送期间新代次保持 PENDING)。V9 的存量收敛/索引与 upsert SQL 需真实 PG,本机无 Docker 时 FlywayMigrationTest 跳过。
2026-09-12 20:38:18 +08:00
windyboy 1e75a81107 fix(pipeline): 修复取报-处理-回填链路的超时、吞吐、回填与 FIFO 问题
外部调用(ACM2-33)
- 共享 MySQL 与自有 PG 全部补有界超时:驱动 connect/socket 超时 + Hikari 池超时
  (注意 Micronaut 的 Hikari 项是毫秒数,不是 Duration 字面量)
- 删除主泵/毒丸路径的 inline 回填:跨库写不再占用 FIFO 关键路径,回填统一由扫描驱动
- 游标自愈:save() 改为「先 UPDATE、缺行 INSERT」,缺行只记一次 ERROR
- Pump/Dispatcher 外层 catch 补 error 日志与失败计数

投递吞吐(ACM2-34)
- Dispatcher 改批量领取;队头退避未到期或首条发送失败即停止本轮(保持目标内保序)
- 有活不再 sleep;删除不可达的 state==SENT 死条件;markSent 移入分支;
  superseded 清理加轮数上限与空 eventId 保护

回填闭环(ACM2-36,V4)
- MISSING(运行时确认行不存在)立即放弃自动重试并告警;暂时性故障达上限后停止自动重试
- 新增 reopen 人工恢复入口;放弃 ≠ 标记已确认(BACKFILL_AT 仍为空,清除前提不成立)
- 扫描改 (BACKFILL_ATTEMPTS, MSG_ID) 公平轮转并排除放弃行,消除全局回填饥饿
- V4 只加字段与必要索引,不按年龄做任何存量推断

切流播种(ACM2-35,V5)
- cutover-watermark 四模式(min/zero/max/显式 ID),默认不播种、代码不做默认选择
- 升级实例拒绝重新播种(SEEDED_AT 为 NULL ≠ 从未消费);播种与水位同语句落库
- 非法取值由启动自检挡下

错误分类与入口契约(ACM2-37)
- 未知 SCHD 子类型改为 UNSUPPORTED,不再静默当全量日计划合并
- ADFT 运营日冲突改走 ProtocolViolation → DEAD(PROTOCOL)
- 兼容入口 receivedAt 缺失回退到注入 Clock;MessageLifecycleGate 强制注入 + 装配断言
- FIFO:主泵只领取 msgId ≤ W,兼容入口登记的行在水位追平前不被领取

时间源与可观测(ACM2-38 / ACM2-41 阶段 0)
- 仓储/处理器/作业全部经注入 Clock;移除 markTerminal/markBackfilled 的 Instant.now() 默认值
- 退避表档位与 max-attempts 对齐并加启动自检
- Micrometer 7 个 gauge(@Context 急切注册)+ /health 与 /metrics 共用积压快照缓存
- 只读迟到检测:监视被放行的空洞 ID 是否后来真的出现,只计数告警、不补入队

Plane: ACM2-33 ACM2-34 ACM2-35 ACM2-36 ACM2-37 ACM2-38 ACM2-41
Tests: 88 → 120(1 skipped 需真实 PG)
2026-09-11 08:08:35 +08:00
windyboy eea11203a2 fix(processing): 收紧消息生命周期与投递约束 2026-09-10 20:39:22 +08:00
windyboy 1183c7522b docs(kdoc): 其余模块注释统一为直白说明
把上一提交没覆盖到的模块也改完,至此仓库内不再有"只写编号、不写说明"的注释。

涉及 33 个文件(生产 24 + 测试 9),包括航班状态模型与合并引擎、事件与留痕模型、
运营日计算、投递器、历史归档作业、编解码与身份、重试与重放、健康指示器、
生命周期装配、以及各自的测试类。

改法与前面一致:先说这段代码做什么,再说为什么这么做,术语第一次出现就地解释
(FLID、OPERATION_DAY、航班版本号、删除通知、待发事件表等)。工单编号
(U07/N02/ACM2-10 之类)已全部移除;段落编号只剩 10 处,全部带文件名位于句尾,
用作延伸阅读,例如"见 docs/flight-state.md §5"。

保留了本来就自解释的行内注释、PgTestSupport 顶部的环境变量默认值表格,
以及 InboxController 里描述待补接口的 TODO。

校验:逐文件做"去注释后比对"(块注释 + 行注释清除、空白归一),33 个文件代码
零差异;另做逐行非注释代码比对,同样零差异。clean test 为 78 passed / 1 skipped。
2026-09-10 11:14:11 +08:00
windyboy 99a0f5f738 refactor(flight-state): SCHD 日计划收敛为缺失保留合并语义并对齐现行设计文档
按现行 docs/flight-state.md(111 行版,§1-§7)全面对齐 domain 包及其消费方,
删除整套指向已退役长版文档(§5.x-§10)的引用与死代码:

- 语义:FlightStateEngine.snapshotState 由"完整快照整体替换"改为 §3.1 合并语义
  ——出现 Set/Replace、缺失保留、标量空串显式清空;DELETED 不被日计划恢复(§3.3)。
- 校验:validateMessage 移除从未接线的报文覆盖范围(scope)参数,只保留 §4 步骤 2
  的声明数量/航班标识/运营日推导校验;ScheduleBody 删除 scopeStart/scopeEnd。
- 删除死代码:domain/Decision.kt、FlightModel 的 SnapshotPatch/UpsertOutcome、
  ProcState.isTerminal/archivable、SnapshotFlag.SEQN_REGRESSION、
  ScheduleRecord.seqn(及 wire FlightRecordXml.SEQN);codec 移除未消费 FFID。
- 删除未接线且引用已退役列(fday/last_message_id)的 SqlDialect 方言脚手架,
  oracle11g README 改为按 V1 现列重建的口径。
- 注释/测试:domain、processing、infra 仓储与 jobs/delivery、配置类及对应测试的
  KDoc 章节引用全部对齐现行 flight-state.md/design.md;FlightStateEngineTest
  重写为合并语义(62/62 通过)。

V1__flight_state_baseline.sql 保留原样(内容注释仍带旧章节号,改动会破坏
已应用迁移的 Flyway checksum,待重建基线或 V2 净迁移时收敛)。
2026-09-09 22:17:04 +08:00
windyboy 879d658159 refactor(flight-state): 按 flight-state.md 审计定稿全量重构脚手架与 SQL (ACM2-31)
- SQL 基线 V1__flight_state_baseline.sql 整体取代 V1.0.0–V1.4.0:
  PIPELINE_LOCK/PROC_STATE/MSG_EVENT/REQ_TRACK/BACKFILL_TODO/FLIGHT_SCHD
  + 8 张资源明细表 + FLIGHT_ROUTE_POINT + SCHD_SNAP_LOG 留痕层
- 废除 FDAY 日代/SCHD_GEN/名单差删:OPERATION_DAY 不可变(应用层校验 +
  条件更新强化 §7.4),STATE 仅 ACTIVE/DELETED,物理清除只在历史归档后
- 处理器化:applyScheduleRecords(§5.1 七步同一事务,重放判定/整包
  DEAD(PROTOCOL)/归属冲突不落地)+ FLOP/FDEL/ADFT(tombstone 仅
  ACTIVE→DELETED,重复 FDEL 幂等不推进版本)
- 投递:KAFKA_SCHD 同 FLID 按最新 STATE_VERSION 合并,被压掉事件关闭,
  TOMBSTONE 发 null 值消息(键缺失=删除旧值 §7.3)
- 回填待办改为业务事务内预登记,消除提交后写待办的崩溃窗口(§7.2/§10)
- XML 解码改为 jackson-dataformat-xml 数据类直接映射(SIS 信封强类型,
  FLTR 开放标签泛型承载)
- 历史归档/物理清除顺序不可颠倒:归档确认成功集才物理删除,未接通删 0 条
- 移除 PUMP_JOB 队列/ReferenceService/FlightStoreDiffTool 等旧机制与测试,
  新增运营日/引擎/快照/FDEL/归档顺序不变性回归测试
2026-09-09 17:53:08 +08:00
windyboy ff6cec08c8 refactor(flight-schd): 按现场 11g 约束将运营航班存储改为宽表 (ACM2-28 修订)
现场环境仅提供 Oracle 11g(无任何 JSON 能力),废除 FLTR_JSON JSONB 整文档存储:

- V1.1.0 迁移重写:FLIGHT_SCHD 改为一行一航班宽表(SCHD.FLTR 标量字段列 +
  1:N 明细集合序列化文本列),SCHD_GEN.FLIDS_JSON 展开为 SCHD_GEN_FLID(FDAY, FLID);
  已应用过旧版迁移的环境需重建 schema 重放
- 契约层:FlightChange/Handler 在线视图改为字段集映射(与 legacy flightInfo
  hash 同构),仓储白名单拒绝未知字段;增量写=字段级合并(hmset 同语义),
  快照=整体替换
- 事件载荷:快照投递与投影重建经 FlightFieldsJson 确定性序列化(键序稳定)
- 影子对拍:FlightStoreDiffTool 改为 PG 宽表列值 vs legacy FLTR JSON 逐字段
  归一化比对,新增嵌套集合比对用例
- 测试:61 用例全绿(不变量门槛 1/2/3、UTC 方言、真实 PG 方言集成、清场五场景)
- 文档:decision-flight-state.md 追加 §8 修订记录(不改写定案历史),design.md 表说明同步

11g 方言移植(ON CONFLICT→MERGE、advisory lock 替代、Flyway/驱动矩阵)、
集合列升子表、类型化列提升等未尽事项另立 Plane issue 跟踪。
2026-09-07 17:04:57 +08:00
windyboy 7b7b61f100 feat(processing): 实现自有 PostgreSQL 运营航班权威存储与单事务闭环 (ACM2-28)
- FS1: 增加 Flyway 迁移 V1.1.0__flight_schd.sql,创建 FLIGHT_SCHD 与 SCHD_GEN
- FS2: 实现 FlightSchdRepository 接口及 JdbcFlightSchdRepository 与 StubFlightSchd,增强 JdbcOps 事务管理
- FS3: 扩展 MessageProcessor 事务 2 与按 FLID 点查视图,合并变更、事件与终态入单事务提交
- FS4: SnapshotFlow SQL 化(批处理 upsert、域内差删、SQL CAS 推进与熔断保护),JobExecutor 接入 PG 清场删除
- FS5: 彻底退役 Redis 权威与写路径,移除 FlightRedisClient、Lua 脚本、健康指示器与配置残留
- FS6: 补齐 U09/U29 不变量门禁(崩溃幂等、CAS 防并发、ADFT 存活保障、非 UTC JVM/会话时区无漂移)与 FlywayMigrationTest
- FS7: 交付影子对拍比较内核 FlightStoreDiffTool 与单元测试
- FS8: 全面回改 decision-flight-state、architecture、design、user-stories 权威文档与规范
2026-09-07 16:12:00 +08:00
windyboy c7b4b527ef feat(ingress): 实现 JDBC 信箱轮询、入站持久化与对拍测试 (U05) 2026-09-07 15:11:33 +08:00