fix(update):修复在线更新检测后缓存问题导致无法正常更新
This commit is contained in:
1 parent
958f6c4d75
commit
0964d9014b
3 files changed
+42
-3
No files matched your search
@@ -115,7 +115,9 @@ func (s *sAdmin) UpdateExecute(ctx context.Context, req *v1.UpdateExecuteReq) (*
|
||||
|
||||
// Get check result to find download URL
|
||||
cached := update.GetManager().GetCheckResult()
|
||||
if cached == nil {
|
||||
// 缓存里有更新但没匹配到平台安装包时强制重查,而不是直接报「没有可用的更新包」:
|
||||
// 典型场景是发行版刚发布、CI 尚未上传资产窗口期的检查结果被缓存,资产几分钟后就位
|
||||
if cached == nil || update.HasUpdateButNoAsset(cached) {
|
||||
// Force a check first
|
||||
result, err := update.CheckForUpdate(ctx, true)
|
||||
if err != nil {
|
||||
|
||||
@@ -114,8 +114,11 @@ func CheckForUpdate(ctx context.Context, force bool) (*CheckResult, error) {
|
||||
// Store ETag for conditional requests
|
||||
manager.lastETag.Store(etag)
|
||||
|
||||
// Cache result
|
||||
setCheckCache(ctx, result)
|
||||
// Cache result。「有更新但没匹配到平台安装包」的结果不写 Redis:TTL 24h 太长,
|
||||
// 会挡住发布窗口期之后的检查拿到完整资产列表(内存结果照常存,供状态展示)
|
||||
if !HasUpdateButNoAsset(result) {
|
||||
setCheckCache(ctx, result)
|
||||
}
|
||||
manager.checkResult.Store(result)
|
||||
|
||||
return result, nil
|
||||
@@ -185,6 +188,14 @@ func fetchLatestRelease(ctx context.Context, conditional bool) (*GitHubRelease,
|
||||
return &release, etag, nil
|
||||
}
|
||||
|
||||
// HasUpdateButNoAsset 判断检查结果是否为「有更新但当前平台没匹配到安装包」。
|
||||
// 典型成因:发行版刚发布、CI 尚未上传资产的窗口期拉到的结果(资产几分钟后才就位)。
|
||||
// 这类结果不可信:不能写缓存,已入库的脏缓存读到后按无效处理,
|
||||
// 执行更新时则强制重查,而不是直接报「没有可用的更新包」。
|
||||
func HasUpdateButNoAsset(r *CheckResult) bool {
|
||||
return r != nil && r.HasUpdate && r.DownloadURL == ""
|
||||
}
|
||||
|
||||
// getCheckCache reads cached check result from Redis.
|
||||
// 缓存是纯优化(TTL 24h),Redis 未配置/不可用时应降级为无缓存、走实时检查,
|
||||
// 绝不能因 g.Redis() 客户端创建失败而 panic(见 goframe-conventions.md 已修复记录)。
|
||||
@@ -205,6 +216,11 @@ func getCheckCache(ctx context.Context) (out *CheckResult) {
|
||||
if err := json.Unmarshal(val.Bytes(), &result); err != nil {
|
||||
return nil
|
||||
}
|
||||
// 「有更新但没匹配到平台安装包」的脏缓存(发布窗口期写入,含旧版本遗留数据)按无效处理,
|
||||
// 让调用方 fallthrough 到实时检查拿完整资产列表
|
||||
if HasUpdateButNoAsset(&result) {
|
||||
return nil
|
||||
}
|
||||
return &result
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,27 @@ func TestCompareVersions(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasUpdateButNoAsset(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
result *CheckResult
|
||||
want bool
|
||||
}{
|
||||
{"nil 结果", nil, false},
|
||||
{"有更新且有安装包", &CheckResult{HasUpdate: true, DownloadURL: "https://example.com/team-api-0.2.14-linux-amd64.tar.gz"}, false},
|
||||
{"无更新且无安装包", &CheckResult{HasUpdate: false, DownloadURL: ""}, false},
|
||||
{"有更新但缺安装包(发布窗口期脏数据)", &CheckResult{HasUpdate: true, DownloadURL: ""}, true},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
if got := HasUpdateButNoAsset(c.result); got != c.want {
|
||||
t.Errorf("HasUpdateButNoAsset(%+v) = %v, want %v", c.result, got, c.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeSemver(t *testing.T) {
|
||||
cases := []struct{ in, want string }{
|
||||
{"0.2.0_39", "0.2.0+39"}, // Makefile git describe 版本:下划线转构建元数据
|
||||
|
||||
Reference in new issue
Block a user