KernelSU 解决方案:解决 schedules.rs 中的重试问题

现状分析

在 KernelSU 的调度系统中,schedules.rs 文件中的 run() 函数负责执行计划任务。当任务队列满时,该函数会将 next_run_at 字段更新为 now + BUSY_RETRY_MS,其中 BUSY_RETRY_MS 是一个预设的重试时间间隔。

问题识别

然而,当任务在重试后再次执行 run() 函数时,系统将 next_run_at 的值视为任务的 due 时间。这导致以下问题:

  1. 任务整体后移:通过 following(due, interval, now) 函数,任务的执行时间会从 next_run_at 开始整体后移。
  2. 幂等保护失效:由于 request_key = schedule-{id}-{due} 的变化,原有的幂等保护机制对原槽位失效,可能导致任务重复执行或执行失败。

示例说明

假设一个任务计划每 60 分钟执行一次,首次执行时间为 10:00。如果在 10:00 时任务队列满,导致任务被推迟,那么下一次执行时间将变为 10:01,接着是 11:01 和 12:01。如果多次遇到队列满的情况,next_run_at 的值会不断累加,导致任务执行时间越来越晚。

解决方案

为了解决这个问题,我们需要确保重试仅改变本次任务的触发时间,而保持原网格与原 request_key 不变。具体实现方法如下:

  1. 调整 run() 函数:在任务重试时,不应更新 next_run_at 字段,而是仅调整本次任务的执行时间。
  2. 保持 request_key 不变:确保在重试过程中,request_key 的值保持不变,以维持幂等保护的有效性。

测试建议

为了验证解决方案的有效性,建议在 schedules_tests.rs 文件中增加 Busy 用例,确保在任务恢复后,next_run_at 仍然符合预期的时间序列,即 first_run_at + k * interval,其中 k 是非负整数,interval 是任务执行间隔。

总结

通过上述调整,我们可以确保任务在重试时不会导致任务整体后移和幂等保护失效的问题,从而提高 KernelSU 调度系统的稳定性和可靠性。