2026-09-07 15:11:33 +08:00
|
|
|
|
package com.gzzn.omms.msgexchange.config
|
2026-09-06 16:13:50 +08:00
|
|
|
|
|
|
|
|
|
|
import io.micronaut.context.annotation.ConfigurationProperties
|
|
|
|
|
|
import java.time.Duration
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* ACMA-8 参数表(v4)初值;阶段 0 现网基线校准。
|
2026-09-09 17:53:08 +08:00
|
|
|
|
* U03(N02):Micronaut 要求嵌套配置类同样标注 @ConfigurationProperties,否则
|
|
|
|
|
|
* msgx.pipeline/schd/identity.* 全部静默回落 Kotlin 默认值。
|
2026-09-06 16:13:50 +08:00
|
|
|
|
*/
|
|
|
|
|
|
@ConfigurationProperties("msgx")
|
|
|
|
|
|
class PipelineProps {
|
|
|
|
|
|
var serviceName: String = "msgexchangeapi"
|
|
|
|
|
|
var registerEureka: Boolean = true
|
|
|
|
|
|
var pipeline: Pipeline = Pipeline()
|
|
|
|
|
|
var schd: Schd = Schd()
|
|
|
|
|
|
var identity: Identity = Identity()
|
|
|
|
|
|
|
2026-09-06 17:58:39 +08:00
|
|
|
|
@ConfigurationProperties("pipeline")
|
2026-09-06 16:13:50 +08:00
|
|
|
|
class Pipeline {
|
|
|
|
|
|
var pollInterval: Duration = Duration.ofSeconds(1) // KEEP 现役节奏
|
|
|
|
|
|
var claimBatch: Int = 50
|
|
|
|
|
|
var maxAttempts: Int = 5 // 处理/投递同值
|
|
|
|
|
|
var backoffMs: List<Long> = listOf(1000, 2000, 4000, 8000, 16000)
|
|
|
|
|
|
var backoffCapMs: Long = 60_000
|
|
|
|
|
|
var headDeadline: Duration = Duration.ofMinutes(10) // 最坏 HOL 上界(毒丸升级)
|
|
|
|
|
|
|
2026-09-10 10:59:58 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* message-lifecycle §5.1 空洞老化:水位 W+1 处的空洞持续超过该时延即判定为永久并放行。
|
|
|
|
|
|
* 取值口径 = 库方承诺的最大提交时延(Q2);太小会把迟到消息判成永久空洞(FIFO 越序风险)。
|
|
|
|
|
|
*/
|
|
|
|
|
|
var maxCommitDelay: Duration = Duration.ofMinutes(5)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* message-lifecycle §5.2 超期补写期限 R:终态后仍无处理标记的行到达该期限即强制补写,
|
|
|
|
|
|
* 保证库方清除前提「边界内无未标记行」在有限时间内成立。
|
|
|
|
|
|
* R ≥ 人工重放期限 + 人工处置期限(Q6);确认前不得下调。
|
|
|
|
|
|
*/
|
|
|
|
|
|
var overdueBackfill: Duration = Duration.ofDays(30)
|
|
|
|
|
|
|
|
|
|
|
|
/** 回填扫描单批条数。 */
|
|
|
|
|
|
var backfillBatch: Int = 100
|
|
|
|
|
|
|
2026-09-06 20:53:14 +08:00
|
|
|
|
/** U07:启动即拉起 Pump/Dispatcher 循环(默认关——需要真实仓储或 msgx.stubs=true 才可安全开启)。 */
|
|
|
|
|
|
var autostart: Boolean = false
|
|
|
|
|
|
|
2026-09-06 18:19:04 +08:00
|
|
|
|
/** N28:attempt ≤ 0(如 FAILED 未递增 attempts 的行)不得抛异常,取下界=首档退避。 */
|
|
|
|
|
|
fun backoffFor(attempt: Int): Long {
|
|
|
|
|
|
val index = (attempt - 1).coerceAtLeast(0)
|
|
|
|
|
|
return backoffMs.getOrNull(index)?.coerceAtMost(backoffCapMs) ?: backoffCapMs
|
|
|
|
|
|
}
|
2026-09-06 16:13:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-06 17:58:39 +08:00
|
|
|
|
@ConfigurationProperties("schd")
|
2026-09-06 16:13:50 +08:00
|
|
|
|
class Schd {
|
|
|
|
|
|
var flushPeriod: Duration = Duration.ofSeconds(3) // KEEP 现役节律
|
|
|
|
|
|
var flushLimit: Int = 500
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-06 17:58:39 +08:00
|
|
|
|
@ConfigurationProperties("identity")
|
2026-09-06 16:13:50 +08:00
|
|
|
|
class Identity {
|
|
|
|
|
|
/** CONFIRM(矩阵 #11):SEQN 重置作用域确认前保持 false,计算集中此处(I3)。 */
|
|
|
|
|
|
var includeDayBoundary: Boolean = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|