diff --git a/src/main/kotlin/com/gzzn/omms/msgexchange/infra/stub/StubRepositories.kt b/src/main/kotlin/com/gzzn/omms/msgexchange/infra/stub/StubRepositories.kt index b1b2db9..19c3517 100644 --- a/src/main/kotlin/com/gzzn/omms/msgexchange/infra/stub/StubRepositories.kt +++ b/src/main/kotlin/com/gzzn/omms/msgexchange/infra/stub/StubRepositories.kt @@ -54,9 +54,9 @@ class StubPipelineLock : PipelineLockRepository { override fun lock() = Unit } +/** 内存版 PROC_STATE:入队幂等,写终态时一并写下回填待办。 */ @Singleton @Requires(property = "msgx.stubs", value = "true") -/** 内存版 PROC_STATE:入队幂等,写终态时一并写下回填待办。 */ class StubProcState(private val clock: Clock = Clock.systemUTC()) : ProcStateRepository { val rows = linkedMapOf() val bound = linkedMapOf() @@ -186,6 +186,7 @@ class StubProcState(private val clock: Clock = Clock.systemUTC()) : ProcStateRep override fun findBackfillDue(now: Instant, overdueBefore: Instant, limit: Int): List = rows.values + .asSequence() .filter { it.state.isTerminal() && it.backfillAt == null && it.backfillAbandonedAt == null } // 超期判据是本地入队时间,与 JDBC 实现保持一致(不用库方时钟的 receivedAt)。 .map { it to (it.enqueuedAt?.let { e -> e < overdueBefore } ?: false) } @@ -194,6 +195,7 @@ class StubProcState(private val clock: Clock = Clock.systemUTC()) : ProcStateRep .sortedWith(compareBy({ it.first.backfillAttempts }, { it.first.msgId })) .take(limit) .map { (row, overdue) -> BackfillDue(row.msgId, row.backfillAttempts, overdue) } + .toList() override fun hasAny(): Boolean = rows.isNotEmpty() @@ -251,11 +253,12 @@ class StubMsgEvents : MsgEventRepository { */ private fun upsertSchd(e: MsgEvent): Long { val existing = rows.values.firstOrNull { it.target == Targets.KAFKA_SCHD && it.partitionKey == e.partitionKey } - val accepted = existing == null || - e.stateVersion > existing.stateVersion || - (e.stateVersion == existing.stateVersion && e.eventType == EventType.TOMBSTONE && existing.eventType != EventType.TOMBSTONE) - if (!accepted) return existing!!.eventId!! - existing?.let { rows.remove(it.eventId!!) } + if (existing != null) { + val accepted = e.stateVersion > existing.stateVersion || + (e.stateVersion == existing.stateVersion && e.eventType == EventType.TOMBSTONE && existing.eventType != EventType.TOMBSTONE) + if (!accepted) return existing.eventId!! + rows.remove(existing.eventId!!) + } val id = ids.incrementAndGet() rows[id] = e.copy( eventId = id, state = EventStatus.PENDING, attempts = 0, nextAttemptAt = null, @@ -327,7 +330,7 @@ class StubFlightState : FlightStateRepository { } val main = FlightMainRow( flid = snapshot.flid, - operationDay = snapshot.operationDay ?: existing?.operationDay, + operationDay = snapshot.operationDay, state = snapshot.state, stateVersion = snapshot.stateVersion, lastMsgId = msgId, @@ -342,7 +345,7 @@ class StubFlightState : FlightStateRepository { val main = mains[flid] ?: return false if (main.state != FlightState.ACTIVE) return false mains[flid] = main.copy(state = FlightState.DELETED, stateVersion = main.stateVersion + 1, lastMsgId = msgId, updatedAt = now) - snapshots[flid] = (snapshots[flid] ?: return true).copy(state = FlightState.DELETED, stateVersion = main.stateVersion + 1) + snapshots[flid] = snapshots[flid]!!.copy(state = FlightState.DELETED, stateVersion = main.stateVersion + 1) return true } @@ -350,7 +353,7 @@ class StubFlightState : FlightStateRepository { val main = mains[flid] ?: return false if (main.state != FlightState.DELETED) return false mains[flid] = main.copy(state = FlightState.ACTIVE, stateVersion = main.stateVersion + 1, lastMsgId = msgId, updatedAt = now) - snapshots[flid] = (snapshots[flid] ?: return true).copy(state = FlightState.ACTIVE, stateVersion = main.stateVersion + 1) + snapshots[flid] = snapshots[flid]!!.copy(state = FlightState.ACTIVE, stateVersion = main.stateVersion + 1) return true } @@ -450,9 +453,9 @@ class StubReqTrack : ReqTrackRepository { } } +/** 内存版共享信箱:可以模拟上游写入、库方清除,并记录哪些行被打上了处理标记。 */ @Singleton @Requires(property = "msgx.stubs", value = "true") -/** 内存版共享信箱:可以模拟上游写入、库方清除,并记录哪些行被打上了处理标记。 */ class StubInbox(private val clock: Clock = Clock.systemUTC()) : CminmsgInboxRepository { val raws = linkedMapOf() private val received = linkedMapOf()