Skip to content

Conversation

@zhy76
Copy link
Member

@zhy76 zhy76 commented Jan 5, 2026

Fixes #6858
fix: ensure status updates are not skipped due to stale cache

What type of PR is this?

/kind bug

What this PR does / why we need it:

Which issue(s) this PR fixes:

Fixes #6858

Special notes for your reviewer:

Does this PR introduce a user-facing change?:

`karmada-controller-manager`: Fixed the issue that AggregatedStatus in rb status may be skipped update due to stale cache

@karmada-bot karmada-bot added kind/bug Categorizes issue or PR as related to a bug. do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. labels Jan 5, 2026
@karmada-bot karmada-bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jan 5, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @zhy76, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a bug where status updates could be inadvertently skipped if the cached object appeared semantically identical to the new status, even when the underlying resource might be out of sync. By transitioning from a full update with an equality check to a direct patch operation, the system now guarantees that all status changes are propagated, effectively preventing inconsistencies caused by stale cache data and improving the reliability of status reporting.

Highlights

  • Fix for Stale Cache Issues: Status updates will no longer be skipped due to stale cache data, ensuring that the latest status is always applied, even if the content appears unchanged.
  • Changed Status Update Mechanism: The UpdateStatus function now utilizes client.Status().Patch with client.Merge instead of client.Status().Update, and the semantic deep equality check has been removed.
  • Enhanced Test Coverage: New test cases have been introduced and existing ones updated to validate the fix, specifically addressing scenarios where status updates might have been incorrectly skipped.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses an issue where status updates could be skipped due to a stale cache. The fix involves removing the equality check before a status update and instead always using a Patch operation. This ensures that status changes, even those that might appear as no-ops to a client with a stale cache (like LastTransitionTime updates), are correctly persisted. The implementation is sound, and the accompanying test changes are excellent, including a major refactoring for better test case generalization and a specific test to cover the bug fix. I have one suggestion to further improve the new test's verification logic.

Comment on lines 173 to 153
verify: func(t *testing.T, c client.Client) {
work := &workv1alpha1.Work{}
assert.NoError(t, c.Get(context.TODO(), types.NamespacedName{Name: "test-work", Namespace: "default"}, work))

cond := meta.FindStatusCondition(work.Status.Conditions, workv1alpha1.WorkApplied)
assert.NotNil(t, cond)
assert.Equal(t, metav1.ConditionTrue, cond.Status)
assert.Equal(t, "AppliedSuccessful", cond.Reason)
},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The verification for this test case is good, but it could be made stronger. The test case update with same WorkApplied condition, should still update (issue #6858) is designed to ensure an update occurs even if only LastTransitionTime changes. The current verify function confirms the condition's Status and Reason, but doesn't check if LastTransitionTime was actually updated.

To make the test more robust and explicitly verify the intended behavior, you could add an assertion to check that LastTransitionTime has been updated to a recent time. Given the initial time is set to one hour in the past, checking that the new time is recent is a safe and effective way to confirm the update.

verify: func(t *testing.T, c client.Client) {
				work := &workv1alpha1.Work{}
				assert.NoError(t, c.Get(context.TODO(), types.NamespacedName{Name: "test-work", Namespace: "default"}, work))

				cond := meta.FindStatusCondition(work.Status.Conditions, workv1alpha1.WorkApplied)
				assert.NotNil(t, cond)
				assert.Equal(t, metav1.ConditionTrue, cond.Status)
				assert.Equal(t, "AppliedSuccessful", cond.Reason)
				assert.True(t, time.Since(cond.LastTransitionTime.Time) < time.Minute, "LastTransitionTime should have been updated")
			},

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The judgment of time differences is somewhat unreliable, and LastTransitionTime is not a key focus of testing. Therefore, it is not recommended to introduce this modification.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, removed LastTransitionTime.

@karmada-bot karmada-bot removed the do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. label Jan 5, 2026
@zhy76 zhy76 force-pushed the fix/status branch 2 times, most recently from 24eed85 to 72cbbd4 Compare January 5, 2026 15:15
@codecov-commenter
Copy link

codecov-commenter commented Jan 5, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 46.54%. Comparing base (310dcff) to head (c4c2799).
⚠️ Report is 12 commits behind head on master.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7077      +/-   ##
==========================================
- Coverage   46.56%   46.54%   -0.02%     
==========================================
  Files         700      700              
  Lines       48089    48087       -2     
==========================================
- Hits        22391    22383       -8     
- Misses      24016    24021       +5     
- Partials     1682     1683       +1     
Flag Coverage Δ
unittests 46.54% <100.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@XiShanYongYe-Chang
Copy link
Member

/retest

@shentupenghui
Copy link

lgtm

@XiShanYongYe-Chang
Copy link
Member

Thanks~
/assign

Copy link
Member

@XiShanYongYe-Chang XiShanYongYe-Chang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks~
/lgtm
Ask @whitewindmills to help take a review.
cc @whitewindmills

Comment on lines 173 to 153
verify: func(t *testing.T, c client.Client) {
work := &workv1alpha1.Work{}
assert.NoError(t, c.Get(context.TODO(), types.NamespacedName{Name: "test-work", Namespace: "default"}, work))

cond := meta.FindStatusCondition(work.Status.Conditions, workv1alpha1.WorkApplied)
assert.NotNil(t, cond)
assert.Equal(t, metav1.ConditionTrue, cond.Status)
assert.Equal(t, "AppliedSuccessful", cond.Reason)
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The judgment of time differences is somewhat unreliable, and LastTransitionTime is not a key focus of testing. Therefore, it is not recommended to introduce this modification.

@karmada-bot karmada-bot added the lgtm Indicates that a PR is ready to be merged. label Jan 6, 2026
@XiShanYongYe-Chang
Copy link
Member

Hi @zhy76, can you help add the release note?

@karmada-bot karmada-bot removed the lgtm Indicates that a PR is ready to be merged. label Jan 6, 2026
@karmada-bot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from xishanyongye-chang. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@zhy76
Copy link
Member Author

zhy76 commented Jan 6, 2026

Hi @zhy76, can you help add the release note?

Done

@zhy76
Copy link
Member Author

zhy76 commented Jan 6, 2026

/retest

@XiShanYongYe-Chang
Copy link
Member

/lgtm

@karmada-bot karmada-bot added the lgtm Indicates that a PR is ready to be merged. label Jan 7, 2026
// even if the content appears unchanged. This avoids issues where stale cache data might cause
// updates to be skipped incorrectly.
// FYI: https://github.com/karmada-io/karmada/issues/6858
if err := c.Status().Patch(ctx, obj, client.MergeFrom(oldObj)); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhy76 thanks for your work, but I think theres‘s no different from the original. if the cached data is expired, I don't think client.MergeFrom(oldObj) can create a meaningful patch. maybe it looks like {}?
therefore, I mean we need to generate a hard-coded patch, or still use the Update method, which may encounter conflicts, but we can use the Retry framework to handle it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand what you mean. The obj currently passed as input might be outdated, and using it to generate a patch is unreliable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Categorizes issue or PR as related to a bug. lgtm Indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AggregatedStatus in rb status may be deleted

6 participants