Files
Web_BLS_RCUAction_Server/openspec/changes/2026-03-10-g5-database-sync/spec.md

3.7 KiB
Raw Blame History

G5 Database Sync and Room Status Aggregation Logic

openspec-proposal

  • 生态包推荐与选型:本次需求纯粹为数据库多环境异步双写及聚合同步架构升级。我们保持着不重复造轮子的极简最佳实践,未引入新的冗余 npm 依赖。坚持复用项目中现有的优秀驱动包 pgnode-postgres作为核心驱动来应对大量行级的高并发插入与聚合。
  • 降级与扩展策略:对现有的 BatchProcessorStatusBatchProcessor 进行原生构造拆解重写,拓展 options(如 omitGuid, dedupeByRoom 等变量配置),以最小侵入业务的方式分离实例对象,挂载 G5 双写。

openspec-apply

针对 Node.js (V8) 和异步并发模型,完成生成和执行如下实施与扩展细则:

1. 异步非阻塞的 Dual-Write 设计方案

  • Event Loop 友好型并行:在执行向 G4 和 G5 环境多库分发数据时,彻底摒弃 await g4_write; await g5_write 的顺序堵塞请求堆栈。采用纯异步的 Promise.all([dbActions]) 把宏任务交由事件循环底层的 I/O 线程池并行发送所有的 INSERT 事务报文,将两座异地数据库的返回时延并集。
  • 配置隔离熔断法:依托 .env 实现对每一向数据库独立挂载的生命周期(如动态通过 ENABLE_G4_SYNCENABLE_G5_SYNC 处理)。任一数据库挂掉带来的错误 PROMISE_REJECTED 在进程捕获后只会独立封停,不会引发系统阻塞或导致另一健康的数据库断供。

2. G5 字段 omitGuid 的剥离控制与瘦身落地

  • G5 中 rcu_action_events_g5 表里的 guid 基于 int4 nextval。这与原本生成的 uuid 类型存在截然冲突。
  • 具体落地:当连接器池检测到 omitGuid = trueG5 模式打开),底层的 SQL INSERT INTO (${columns}) 将会动态清洗掉 guid 和所绑定的 $n 占位符。把主键控制权彻底返还给 PostgreSQL 内部机制Node 层专注传输,达到结构和时效的最简合并。

3. Room Status: 房间聚合锁与 Upsert (ON CONFLICT DO UPDATE)

  • 去重逻辑优化与 dedupeByRoom:针对 room_status_moment_g5 中限定 (hotel_id, room_id) 是唯一的联合主键特质,如果仍然通过旧结构缓存,会产生频繁覆盖导致的 JSON 散件丢失。本次通过 Node 层注入 dedupeByRoom 拦截校验法:缓冲器使用 ${hotel_id}:${room_id} 的更底层维度合并哈希。同一房间内设备的任何 JSONB 数组比如 dev_loops 都先进行底层 || 合并及时间对比去重,然后一次性下发大包。
  • SQL 更新映射:由于 device_id 不再具有唯一性维度,我们执行基于 PostgreSQL 的合并操作:在冲突 EXCLUDED 对象中强制替换最新上报设备 $device_id = EXCLUDED.device_id。并且彻底抽去了 Node 更新时间戳的过程,让权给表上的 AFTER/BEFORE UPDATE 原生触发器处理 ts_ms。符合强数据库型开发的完美最佳实践。

4. 废弃冗余数据占用 (udp_raw & details)

由于上游报文及 JSON 持久化逻辑逐步升级,对于 G4 以及后续加入的 G5 库,在映射中全量废除了直接对 udp_raw 回追文本和对 details JSONB 的业务数据的多余存储。

  • 具体拦截处理:我们在 processor/index.js commonFields 中将 udp_raw 强赋值为 null;同理对于所有的 payload 解析结果,details 也改为了强置空(null)。相应的单元测试套件已被更新修改以校验拦截有效性。
  • 目的:通过这两项高频臃肿字典的精减裁剪,可极大缩小单行落盘宽表的体积,减轻 PostgreSQL 序列化负担及提升 UPSERT 时延,而数据库中的字段保留以用于结构向后兼容。