From 7479b4b13ed1b9a59f02bf956eaacb8dd8045816 Mon Sep 17 00:00:00 2001 From: xml Date: Fri, 10 Apr 2026 14:59:01 +0800 Subject: [PATCH] Fix: Repair randomized timer for first-time intranet updates * When switching from public network to intranet, force-refresh the timer with a randomized value. * Use a randomized value for the initial timer upon each restart, then switch to fixed values for subsequent timer initiations Bug: https://pms.uniontech.com/bug-view-355587.html --- ...66\345\231\250\347\255\226\347\225\245.md" | 10 ++++++ src/internal/config/config.go | 23 +++++++++--- src/lastore-daemon/manager.go | 22 +++++++++++- src/lastore-daemon/manager_unit.go | 35 ++++++++++--------- 4 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 "docs/lastoreAutoCheck\345\256\232\346\227\266\345\231\250\347\255\226\347\225\245.md" diff --git "a/docs/lastoreAutoCheck\345\256\232\346\227\266\345\231\250\347\255\226\347\225\245.md" "b/docs/lastoreAutoCheck\345\256\232\346\227\266\345\231\250\347\255\226\347\225\245.md" new file mode 100644 index 000000000..b98287524 --- /dev/null +++ "b/docs/lastoreAutoCheck\345\256\232\346\227\266\345\231\250\347\255\226\347\225\245.md" @@ -0,0 +1,10 @@ +lastoreAutocheck.timer定时器跟两个设定值有关系:CheckInterval和StartCheckRange有密切关系 +- CheckInterval是一个固定值 +- 是一个范围值,用来在这个返回生成一个随机值 + +公网行为: +系统第一次开机(装完机后第一次触发检查更新前都算,主要依据就是lastCheckTime的值,如果是一个空值,则认为是第一次启动),则直接使用随机值来设定定时器,之后都使用固定值+随机值的组合来设置定时器,关机不影响时间计算。意思就是说,下次启动后,会与上次检查的时间进行比较,不足时间则补足剩余时间+随机值作为这次定时器,>=7天则直接使用随机值作为定时器。 + +私网行为: +- 每次系统启动的时候第一次定时器是一个StartCheckRange中的随机值,后面按照固定值CheckInterval轮询。 +- 当从公网切换到私网的时候,需要当成第一次启动来处理,因此需要设置一个标志来表明当前是第一次启动。 \ No newline at end of file diff --git a/src/internal/config/config.go b/src/internal/config/config.go index 621541e15..5428e6b3b 100644 --- a/src/internal/config/config.go +++ b/src/internal/config/config.go @@ -221,7 +221,7 @@ const ( dSettingsKeySecurityRepoType = "security-repo-type" dSettingsKeyPlatformRepoComponents = "platform-repo-components" DSettingsKeyIncrementalUpdate = "incremental-update" - dSettingsKeyIntranetUpdate = "intranet-update" + DSettingsKeyIntranetUpdate = "intranet-update" dSettingsKeyGetHardwareIdByHelper = "hardware-id-from-helper" dSettingsKeyDeliveryRemoteDownloadGlobalLimit = "delivery-remote-download-global-limit" dSettingsKeyDeliveryRemoteUploadGlobalLimit = "delivery-remote-upload-global-limit" @@ -309,7 +309,7 @@ func getConfigFromDSettings() *Config { c.IncrementalUpdate = v.Value().(bool) } - v, err = c.dsLastoreManager.Value(0, dSettingsKeyIntranetUpdate) + v, err = c.dsLastoreManager.Value(0, DSettingsKeyIntranetUpdate) if err != nil { logger.Warning(err) } else { @@ -793,12 +793,20 @@ func getConfigFromDSettings() *Config { _, err = c.dsLastoreManager.ConnectValueChanged(func(key string) { logger.Infof("config update: key=%s", key) switch key { - case dSettingsKeyIntranetUpdate: - v, err = c.dsLastoreManager.Value(0, dSettingsKeyIntranetUpdate) + case DSettingsKeyIntranetUpdate: + v, err = c.dsLastoreManager.Value(0, DSettingsKeyIntranetUpdate) if err != nil { logger.Warning(err) } else { - c.IntranetUpdate = v.Value().(bool) + oldValue := c.PlatformUpdate + newValue := v.Value().(bool) + c.IntranetUpdate = newValue + c.dsettingsChangedCbMapMu.Lock() + cb := c.dsettingsChangedCbMap[key] + if cb != nil { + go cb(oldValue, newValue) + } + c.dsettingsChangedCbMapMu.Unlock() } case DSettingsKeyPlatformUpdate: v, err = c.dsLastoreManager.Value(0, DSettingsKeyPlatformUpdate) @@ -1073,6 +1081,11 @@ func (c *Config) SetAllowInstallRemovePkgExecPaths(paths []string) error { // return c.save(dSettingsKeyNeedDownloadSize, size) // } +func (c *Config) SetLastCheckTime(lastCheckTime time.Time) error { + c.LastCheckTime = lastCheckTime + return c.save(dSettingsKeyLastCheckTime, c.LastCheckTime.Format(configTimeLayout)) +} + func (c *Config) SetDownloadSpeedLimitConfig(config string) error { c.DownloadSpeedLimitConfig = config return c.save(dSettingsKeyDownloadSpeedLimit, config) diff --git a/src/lastore-daemon/manager.go b/src/lastore-daemon/manager.go index 921b7311d..7ca692bfd 100644 --- a/src/lastore-daemon/manager.go +++ b/src/lastore-daemon/manager.go @@ -111,6 +111,8 @@ type Manager struct { logFds []*os.File logFdsMu sync.Mutex logTmpFile *os.File + + isAutoCheckTimerFirstRun bool } /* @@ -243,6 +245,20 @@ func (m *Manager) initDSettingsChangedHandle() { logger.Info("AutoDownloadUpdates changed to:", autoDownloadUpdates) } }) + m.config.ConnectConfigChanged(config.DSettingsKeyIntranetUpdate, func(oldValue, newValue interface{}) { + intranetUpdate := newValue.(bool) + if intranetUpdate { + // 当开启内网更新时,将上次检查时间设置为0,并重新触发lastoreAutoCheck定时器 + if err := m.config.SetLastCheckTime(time.Unix(0, 0)); err != nil { + logger.Warningf("SetLastCheckTime failed: %v", err) + } + m.isAutoCheckTimerFirstRun = true + if err := m.updateAutoCheckSystemUnit(); err != nil { + logger.Warningf("updateAutoCheckSystemUnit failed: %v", err) + } + m.isAutoCheckTimerFirstRun = false + } + }) } // recreateSystem 重新创建system对象,用于incremental-update热更新 @@ -308,7 +324,11 @@ func (m *Manager) TryToStartAutoCheck() { if isTimerUnitFileExists(lastoreAutoCheck) { return } - m.updateAutoCheckSystemUnit() + m.isAutoCheckTimerFirstRun = true + if err := m.updateAutoCheckSystemUnit(); err != nil { + logger.Warning(err) + } + m.isAutoCheckTimerFirstRun = false } func (m *Manager) delUpdatePackage(sender dbus.Sender, jobName string, packages string) (*Job, error) { diff --git a/src/lastore-daemon/manager_unit.go b/src/lastore-daemon/manager_unit.go index ffe510694..c12495f54 100644 --- a/src/lastore-daemon/manager_unit.go +++ b/src/lastore-daemon/manager_unit.go @@ -320,29 +320,30 @@ func (m *Manager) handleAbortAutoDownload() { func (m *Manager) getNextUpdateDelay() time.Duration { elapsed := time.Since(m.config.LastCheckTime) remained := m.config.CheckInterval - elapsed - if remained < 0 { + if remained < _minDelayTime { + // ensure delay at least have 10 seconds return _minDelayTime } - // ensure delay at least have 10 seconds - return remained + _minDelayTime + + return remained } func (m *Manager) getNextAutoCheckDelay() int { - checkInterval := m.config.CheckInterval - if checkInterval < 0 { - checkInterval = 0 - } - - elapsed := time.Since(m.config.LastCheckTime) - remained := int((checkInterval - elapsed) / time.Second) - if remained < 0 { - remained = 0 + if m.config.IntranetUpdate { + if m.isAutoCheckTimerFirstRun { + randomDelay := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(m.config.StartCheckRange[1]-m.config.StartCheckRange[0]) + m.config.StartCheckRange[0] + return randomDelay + } else { + checkInterval := m.config.CheckInterval + if checkInterval < 0 { + checkInterval = 0 + } + return int((checkInterval) / time.Second) + } + } else { + randomDelay := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(m.config.StartCheckRange[1]-m.config.StartCheckRange[0]) + m.config.StartCheckRange[0] + return int(m.getNextUpdateDelay()/time.Second) + randomDelay } - - randomDelay := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(m.config.StartCheckRange[1]-m.config.StartCheckRange[0]) + m.config.StartCheckRange[0] - autoCheckDelay := remained + randomDelay - logger.Infof("get next auto check delay, StartCheckRange=%v, randomDelay=%d, autoCheckDelay=%d", m.config.StartCheckRange, randomDelay, autoCheckDelay) - return autoCheckDelay } // isAllowedToTriggerSystemEvent checks if the uid is allowed to trigger system events