fix(jobs): 留痕清理独立接通历史存储开关;精简死逻辑并对齐陈旧注释

This commit is contained in:
windyboy
2026-09-11 14:26:44 +08:00
parent d909a88167
commit a84751bf03
14 changed files with 75 additions and 72 deletions
@@ -160,8 +160,6 @@ data class Backlog(
interface MsgEventRepository {
fun insertAll(events: List<MsgEvent>): List<Long>
fun headUnsent(target: String): MsgEvent?
fun claimBatch(target: String, limit: Int): List<MsgEvent>
/** 挑出待发的整态事件,同一条航班只取版本最高的那一条(中间的版本不用发)。 */
@@ -227,9 +225,6 @@ interface FlightStateRepository {
* 历史存储没接通时,调用方必须传空集合,也就是一条都不删。
*/
fun purgeArchived(flids: Collection<String>): Int
/** 运营日还没定下来的航班有多少条(观测用;这些航班暂时不参与清理)。 */
fun countOperationDayNull(): Int
}
/** 日计划处理留痕:只追加、不参与业务判断,一次处理(含重放)记一行,写失败不影响业务。 */
@@ -0,0 +1,12 @@
package com.gzzn.omms.msgexchange.infra.persistence
import java.time.Instant
/**
* 留痕清理端口:物理删除指定时刻之前的 `SCHD_SNAP_LOG` 行。
*
* 只依赖自有 PG,不依赖历史存储开关——留痕是本地可重建记录,清理不需要外部归档确认。
*/
fun interface SnapshotLogPurge {
fun purgeBefore(instant: Instant): Int
}
@@ -23,6 +23,7 @@ import com.gzzn.omms.msgexchange.infra.persistence.PipelineTransactionManager
import com.gzzn.omms.msgexchange.infra.persistence.ProcStateRepository
import com.gzzn.omms.msgexchange.infra.persistence.ReqTrackRepository
import com.gzzn.omms.msgexchange.domain.SnapshotLogEntry
import com.gzzn.omms.msgexchange.infra.persistence.SnapshotLogPurge
import com.gzzn.omms.msgexchange.infra.persistence.SnapshotLogRepository
import io.micronaut.context.annotation.Requires
import jakarta.inject.Singleton
@@ -450,13 +451,6 @@ class JdbcMsgEventRepository(
)
}
override fun headUnsent(target: String): MsgEvent? =
ds.queryOne(
"SELECT * FROM msg_event WHERE target = ? AND state = 'PENDING' ORDER BY event_id ASC LIMIT 1",
{ ps -> ps.setString(1, target) },
::mapEvent,
)
override fun claimBatch(target: String, limit: Int): List<MsgEvent> =
ds.query(
"SELECT * FROM msg_event WHERE target = ? AND state = 'PENDING' ORDER BY event_id ASC LIMIT ?",
@@ -682,9 +676,6 @@ class JdbcFlightStateRepository(
return purged
}
override fun countOperationDayNull(): Int =
ds.queryOne("SELECT count(*) AS n FROM flight_schd WHERE operation_day IS NULL", {}) { rs -> rs.getInt("n") } ?: 0
// ---- 内部实现 ----
private fun bindMain(
@@ -825,7 +816,7 @@ class JdbcFlightStateRepository(
class JdbcSnapshotLogRepository(
private val ds: DataSource,
private val clock: Clock,
) : SnapshotLogRepository {
) : SnapshotLogRepository, SnapshotLogPurge {
/** 只追加写;这里不抛异常,写失败由调用方捕获并记为指标。 */
override fun append(entry: SnapshotLogEntry) {
ds.update(
@@ -848,6 +839,17 @@ class JdbcSnapshotLogRepository(
},
)
}
/** 留痕清理:收信时间与覆盖窗尾都早于分界点的行物理删除(走 idx_snaplog_cleanup)。 */
override fun purgeBefore(instant: Instant): Int =
ds.update(
"DELETE FROM schd_snap_log WHERE scope_end < ? AND recv_at < ?",
{ ps ->
val cutoffDay = java.time.LocalDate.ofInstant(instant, java.time.ZoneId.of("Asia/Shanghai"))
ps.setDate(1, java.sql.Date.valueOf(cutoffDay))
ps.setTimestamp(2, instant.toSqlTimestamp())
},
)
}
@Singleton
@@ -20,8 +20,7 @@ class ProcFailure(
private val procState: ProcStateRepository,
val scheduler: FailureScheduler,
) {
/** @return 是否已经落到终态:DEAD 是终态,FAILED 还会再试 */
fun fail(head: ProcState, ec: ErrorClass, reason: String): Boolean {
fun fail(head: ProcState, ec: ErrorClass, reason: String) {
val attempts = head.attempts + 1
if (scheduler.exhausted(attempts)) {
procState.markTerminal(
@@ -31,7 +30,6 @@ class ProcFailure(
lastError = "$reason; attempts=$attempts",
now = scheduler.now(),
)
return true
}
procState.update(
head.msgId, ProcStatus.FAILED,
@@ -40,6 +38,5 @@ class ProcFailure(
errorClass = ec,
lastError = reason,
)
return false
}
}
@@ -19,6 +19,7 @@ import com.gzzn.omms.msgexchange.infra.persistence.MailboxRow
import com.gzzn.omms.msgexchange.infra.persistence.MailboxMarkResult
import com.gzzn.omms.msgexchange.infra.persistence.FlightStateRepository
import com.gzzn.omms.msgexchange.infra.persistence.MsgEventRepository
import com.gzzn.omms.msgexchange.infra.persistence.SnapshotLogPurge
import com.gzzn.omms.msgexchange.infra.persistence.PersistOutcome
import com.gzzn.omms.msgexchange.infra.persistence.PipelineLockRepository
import com.gzzn.omms.msgexchange.infra.persistence.PipelineTransactionManager
@@ -233,9 +234,6 @@ class StubMsgEvents : MsgEventRepository {
id
}
override fun headUnsent(target: String): MsgEvent? =
rows.values.filter { it.target == target && it.state == EventStatus.PENDING }.minByOrNull { it.eventId!! }
override fun claimBatch(target: String, limit: Int): List<MsgEvent> =
rows.values.filter { it.target == target && it.state == EventStatus.PENDING }.sortedBy { it.eventId!! }.take(limit)
@@ -344,12 +342,11 @@ class StubFlightState : FlightStateRepository {
return n
}
override fun countOperationDayNull(): Int = mains.values.count { it.operationDay == null }
}
@Singleton
@Requires(property = "msgx.stubs", value = "true")
class StubSnapshotLog : SnapshotLogRepository {
class StubSnapshotLog : SnapshotLogRepository, SnapshotLogPurge {
val entries = mutableListOf<SnapshotLogEntry>()
fun clear() = entries.clear()
@@ -357,6 +354,12 @@ class StubSnapshotLog : SnapshotLogRepository {
override fun append(entry: SnapshotLogEntry) {
entries.add(entry)
}
override fun purgeBefore(instant: Instant): Int {
val before = entries.size
entries.removeAll { it.recvAt < instant }
return before - entries.size
}
}
@Singleton