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 权威文档与规范
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
package com.gzzn.omms.msgexchange.jobs
|
||||
|
||||
import com.gzzn.omms.msgexchange.infra.redis.FlightRedisClient
|
||||
import com.gzzn.omms.msgexchange.infra.redis.RedisScript
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.FlightStateRepository
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.FlightSchdRepository
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.MsgEventRepository
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.PumpJobRepository
|
||||
import com.gzzn.omms.msgexchange.domain.MsgEvent
|
||||
@@ -33,21 +31,31 @@ class JobExecutor(
|
||||
*/
|
||||
@Singleton
|
||||
class HistorySweepJob(
|
||||
private val redis: FlightRedisClient,
|
||||
// TODO(阶段2): esFlightHts.saveSync(history) 返回成功集(同步写,不经事件 ack 回查)
|
||||
private val flightSchd: FlightSchdRepository,
|
||||
) {
|
||||
companion object {
|
||||
var historyPicker: ((Map<String, String>) -> Map<String, String>)? = null
|
||||
var esArchiver: ((Map<String, String>) -> Set<String>)? = null
|
||||
var cutoffProvider: (() -> String?)? = null
|
||||
}
|
||||
|
||||
fun run() {
|
||||
val all = redis.hgetAllFlightInfo()
|
||||
val all = flightSchd.findAll()
|
||||
val history = pickHistory(all) // U10/T07:saveSync 接线前判史为空集——禁止“全量可删”默认
|
||||
val success = emptyList<String>() // TODO(阶段2): esFlightHts.saveSync(history)(返回成功集后再接线删除)
|
||||
val success = esArchiver?.invoke(history) ?: emptySet() // 仅收集已确认写入 ES 的成功 FLID 集合
|
||||
if (success.isNotEmpty()) {
|
||||
redis.eval(RedisScript.BATCH_DELETE, delFields = success)
|
||||
flightSchd.deleteByFlids(success) // FS2/FS4:仅删除已确认写入 ES 的成功集合,分批参数化删除
|
||||
}
|
||||
val cutoff = cutoffProvider?.invoke()
|
||||
if (cutoff != null) {
|
||||
flightSchd.deleteGenBefore(cutoff)
|
||||
}
|
||||
}
|
||||
|
||||
/** U10/T07(修订):接入 ES success 集之前的门禁——占位默认返回空集;
|
||||
* 现役五条判史规则(SODT 3 天 / CNCL 1 小时 / 备降 / 离港 / 到港)golden 通过后才允许接线。 */
|
||||
private fun pickHistory(all: Map<String, String>): Map<String, String> = emptyMap() // TODO(阶段2)
|
||||
private fun pickHistory(all: Map<String, String>): Map<String, String> =
|
||||
historyPicker?.invoke(all) ?: emptyMap()
|
||||
}
|
||||
|
||||
/** 流程 5 runJob(ARCHIVE):3:00 归档——1 天前且仅终态可迁(矩阵 #12)。 */
|
||||
@@ -63,19 +71,18 @@ class ArchiveJob(
|
||||
/** 流程 7:阶段 B 投影重建——切入阶段 B 时全量重建一次,此后增量走事件。 */
|
||||
@Singleton
|
||||
class ProjectionRebuildJob(
|
||||
private val flightState: FlightStateRepository,
|
||||
private val flightSchd: FlightSchdRepository,
|
||||
private val msgEvents: MsgEventRepository,
|
||||
) {
|
||||
fun run() {
|
||||
for (day in activeDays()) {
|
||||
val flights = flightState.findByDay(day)
|
||||
val flights = flightSchd.findByDay(day)
|
||||
flights.forEach { (flid, payload) ->
|
||||
msgEvents.insertSync(
|
||||
listOf(MsgEvent(target = Targets.REDIS_FLIGHT_INFO, partitionKey = flid, payloadJson = payload)),
|
||||
listOf(MsgEvent(target = Targets.KAFKA_SCHD, partitionKey = flid, payloadJson = payload)),
|
||||
)
|
||||
}
|
||||
}
|
||||
// 重建完成前旧 Redis 视图继续服务(数据同源,仅短暂滞后)
|
||||
}
|
||||
|
||||
private fun activeDays(): List<String> = emptyList() // TODO(阶段B)
|
||||
|
||||
Reference in New Issue
Block a user