From a340b4b63155cf39b7eac76cac19ad8c140048ef Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Tue, 30 Dec 2025 14:25:09 +0800 Subject: [PATCH] Fix version info upgrade notification not clearing after cluster upgrade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The isUpdateNeeded function now also checks if the server version has changed since the last version check. This ensures that when a cluster is upgraded to a new version, the version check is triggered and any outdated upgrade notifications are cleared. Previously, only the LastUpdateTime was checked, which meant that if a cluster was upgraded within an hour of the last version check, the outdated notification would persist until the next hourly check. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 Signed-off-by: majiayu000 <1835304752@qq.com> --- service/frontend/version_checker.go | 13 ++- service/frontend/version_checker_test.go | 106 +++++++++++++++++++++++ 2 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 service/frontend/version_checker_test.go diff --git a/service/frontend/version_checker.go b/service/frontend/version_checker.go index eed8c4548a..03f7096c54 100644 --- a/service/frontend/version_checker.go +++ b/service/frontend/version_checker.go @@ -120,8 +120,17 @@ func (vc *VersionChecker) performVersionCheck( } func isUpdateNeeded(metadata *persistence.GetClusterMetadataResponse) bool { - return metadata.VersionInfo == nil || (metadata.VersionInfo.LastUpdateTime != nil && - metadata.VersionInfo.LastUpdateTime.AsTime().Before(time.Now().Add(-time.Hour))) + if metadata.VersionInfo == nil { + return true + } + // Check if the server version has changed since last version check. + // This ensures upgrade notifications are cleared after cluster upgrade. + if metadata.VersionInfo.Current == nil || + metadata.VersionInfo.Current.Version != headers.ServerVersion { + return true + } + return metadata.VersionInfo.LastUpdateTime != nil && + metadata.VersionInfo.LastUpdateTime.AsTime().Before(time.Now().Add(-time.Hour)) } func (vc *VersionChecker) createVersionCheckRequest(metadata *persistence.GetClusterMetadataResponse) (*versioninfo.VersionCheckRequest, error) { diff --git a/service/frontend/version_checker_test.go b/service/frontend/version_checker_test.go new file mode 100644 index 0000000000..63d574b900 --- /dev/null +++ b/service/frontend/version_checker_test.go @@ -0,0 +1,106 @@ +package frontend + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + versionpb "go.temporal.io/api/version/v1" + persistencespb "go.temporal.io/server/api/persistence/v1" + "go.temporal.io/server/common/headers" + "go.temporal.io/server/common/persistence" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestIsUpdateNeeded(t *testing.T) { + tests := []struct { + name string + metadata *persistence.GetClusterMetadataResponse + want bool + }{ + { + name: "nil VersionInfo returns true", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: nil, + }, + }, + want: true, + }, + { + name: "nil Current returns true", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: nil, + LastUpdateTime: timestamppb.New(time.Now()), + }, + }, + }, + want: true, + }, + { + name: "different server version returns true", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: &versionpb.ReleaseInfo{ + Version: "0.0.0-old-version", + }, + LastUpdateTime: timestamppb.New(time.Now()), + }, + }, + }, + want: true, + }, + { + name: "same version with recent LastUpdateTime returns false", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: &versionpb.ReleaseInfo{ + Version: headers.ServerVersion, + }, + LastUpdateTime: timestamppb.New(time.Now()), + }, + }, + }, + want: false, + }, + { + name: "same version with old LastUpdateTime returns true", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: &versionpb.ReleaseInfo{ + Version: headers.ServerVersion, + }, + LastUpdateTime: timestamppb.New(time.Now().Add(-2 * time.Hour)), + }, + }, + }, + want: true, + }, + { + name: "same version with nil LastUpdateTime returns false", + metadata: &persistence.GetClusterMetadataResponse{ + ClusterMetadata: &persistencespb.ClusterMetadata{ + VersionInfo: &versionpb.VersionInfo{ + Current: &versionpb.ReleaseInfo{ + Version: headers.ServerVersion, + }, + LastUpdateTime: nil, + }, + }, + }, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := isUpdateNeeded(tt.metadata) + require.Equal(t, tt.want, got) + }) + } +}