From e19e904179caf7f2f97fd13b162fe6b8db75d739 Mon Sep 17 00:00:00 2001 From: anime Date: Sat, 11 Oct 2025 00:34:15 +0800 Subject: [PATCH] fix(channel): handle dynamic frequency updates - replace infinite sleep loop with time.Ticker to avoid goroutine leaks - add immediate initial test execution before ticker starts - implement frequency change detection and ticker recreation - ensure proper ticker cleanup when loop exits or feature disabled --- controller/channel-test.go | 51 ++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/controller/channel-test.go b/controller/channel-test.go index 4778ff0c7..55b187ebb 100644 --- a/controller/channel-test.go +++ b/controller/channel-test.go @@ -617,22 +617,47 @@ var autoTestChannelsOnce sync.Once func AutomaticallyTestChannels() { autoTestChannelsOnce.Do(func() { - for { - if !operation_setting.GetMonitorSetting().AutoTestChannelEnabled { - time.Sleep(10 * time.Minute) - continue - } - frequency := operation_setting.GetMonitorSetting().AutoTestChannelMinutes - common.SysLog(fmt.Sprintf("automatically test channels with interval %d minutes", frequency)) + go func() { for { - time.Sleep(time.Duration(frequency) * time.Minute) - common.SysLog("automatically testing all channels") - _ = testAllChannels(false) - common.SysLog("automatically channel test finished") if !operation_setting.GetMonitorSetting().AutoTestChannelEnabled { - break + time.Sleep(10 * time.Minute) + continue } + + frequency := operation_setting.GetMonitorSetting().AutoTestChannelMinutes + common.SysLog(fmt.Sprintf("starting tests with interval %d minutes", frequency)) + ticker := time.NewTicker(time.Duration(frequency) * time.Minute) + + // 使用匿名函数来绑定 ticker 的生命周期 + func() { + defer ticker.Stop() + + // 立即执行一次 + common.SysLog("automatically testing all channels (initial run)") + _ = testAllChannels(false) + common.SysLog("automatically channel test finished") + + // 开始循环等待后续的 tick + for { + select { + case <-ticker.C: + // 检查是否需要退出或重新配置 + if !operation_setting.GetMonitorSetting().AutoTestChannelEnabled { + return + } + newFrequency := operation_setting.GetMonitorSetting().AutoTestChannelMinutes + if newFrequency != frequency { + return + } + + // 执行定时任务 + common.SysLog("automatically testing all channels") + _ = testAllChannels(false) + common.SysLog("automatically channel test finished") + } + } + }() } - } + }() }) }