From d47e9fbf95faac42939016e5116c3f98b095c003 Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Mon, 9 Feb 2026 17:29:32 +0800 Subject: [PATCH] fix(ActionScheduler): initialize wheel tick baseline before launch to avoid check-to-wheel startup drift --- .../action/dispatcher/scheduler/ActionScheduler.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt index 8a864d7b..b1bb7b46 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt @@ -149,11 +149,12 @@ class ActionScheduler : AgentRunningSubModule, Void>() return null } - suspend fun CoroutineScope.wheel(launchingTime: ZonedDateTime) { + suspend fun CoroutineScope.wheel(launchingTime: ZonedDateTime, primaryTickAdvanceTime: Long) { // 计算当前距离时内下次任务的剩余时间, 秒级推进 val launchingHour = launchingTime.hour var tick = launchingTime.minute * 60 + launchingTime.second - var lastTickAdvanceTime = System.nanoTime() + var lastTickAdvanceTime = primaryTickAdvanceTime + while (isActive) { // tick 推进(nano -> second) val current = System.nanoTime() @@ -213,9 +214,14 @@ class ActionScheduler : AgentRunningSubModule, Void>() // 判断是否该步入下一小时 var shouldWait: Boolean? = null var currentTime: ZonedDateTime? = null + var primaryTickAdvanceTime: Long? = null checkThenExecute { currentTime = it shouldWait = actionsGroupByHour[it.hour].isEmpty() + // 由于 wheel 的启动时间可能存在延迟,而时内推进由 nanoTime 保证不会漏发, + // 正常的时序结束又由 tick 是否触顶、当前时是否存在额外任务触发, + // 而启动时无触发保障,此时一并初始化 tick 推进时间,足以应对 check 与 wheel 间的这段时间间隔 + primaryTickAdvanceTime = System.nanoTime() } // 如果该时无任务则等待,插入事件可提前唤醒 @@ -226,7 +232,7 @@ class ActionScheduler : AgentRunningSubModule, Void>() } // 唤醒进行时间轮循环 - wheel(currentTime!!) + wheel(currentTime!!, primaryTickAdvanceTime!!) } } }