Files
msgexchange-v2/src/main/kotlin/com/gzzn/omms/msgexchange/PipelineLifecycle.kt
T

65 lines
2.3 KiB
Kotlin
Raw Normal View History

package com.gzzn.omms.msgexchange
import com.gzzn.omms.msgexchange.delivery.Dispatcher
import com.gzzn.omms.msgexchange.ingress.InboxPoller
import com.gzzn.omms.msgexchange.processing.Pump
import com.gzzn.omms.msgexchange.jobs.JobRunner
import io.micronaut.context.annotation.Requires
import io.micronaut.runtime.event.annotation.EventListener
import io.micronaut.runtime.server.event.ServerStartupEvent
import jakarta.annotation.PreDestroy
import jakarta.inject.Singleton
/**
* 管道的启动与停机:服务起来后拉起 inbox 轮询、主泵、投递三条循环,每条各占一个专用平台线程;
* 停机时先让它们各自收尾,再中断线程解除 sleep 并等待退出。
*
* 只有配置 msgx.pipeline.autostart=true 时才装配,默认不开:得有真实仓储或者 msgx.stubs=true
* 才能安全自启。
*/
@Requires(property = "msgx.pipeline.autostart", value = "true")
@Singleton
class PipelineLifecycle(
private val poller: InboxPoller,
private val pump: Pump,
private val dispatcher: Dispatcher,
private val jobRunner: JobRunner,
) {
private val log = org.slf4j.LoggerFactory.getLogger(PipelineLifecycle::class.java)
private val threads = mutableListOf<Thread>()
@Volatile
private var started = false
@EventListener
fun start(event: ServerStartupEvent) {
startIfNeeded()
}
private fun startIfNeeded() {
if (started) return
// 管道参数合法性已由 PipelineConfigCheck 在启动时无条件校验(CLM-7);
// 这里只负责拉起循环线程。
started = true
threads += spawn("msgx-inbox-poller", poller::loop)
threads += spawn("msgx-pump", pump::loop)
threads += spawn("msgx-dispatcher", dispatcher::loop)
jobRunner.start()
log.info("pipeline loops started (inbox-poller, pump, dispatcher, jobs)")
}
private fun spawn(name: String, body: () -> Unit): Thread =
Thread.ofPlatform().name(name).daemon(true).start { body() }
@PreDestroy
fun stop() {
poller.stop()
pump.stop()
dispatcher.stop()
jobRunner.stop()
threads.forEach { it.interrupt() } // 打断 sleep,让循环立刻醒过来退出,而不是干等一轮间隔
threads.forEach { runCatching { it.join(3000) } }
log.info("pipeline loops stopped")
}
}