Skip to content

re-fetch work status inside RetryOnConflict loop#7694

Open
Varshar21-07 wants to merge 1 commit into
karmada-io:masterfrom
Varshar21-07:fix/issue-7227-stale-fullya-applied-condition
Open

re-fetch work status inside RetryOnConflict loop#7694
Varshar21-07 wants to merge 1 commit into
karmada-io:masterfrom
Varshar21-07:fix/issue-7227-stale-fullya-applied-condition

Conversation

@Varshar21-07

Copy link
Copy Markdown

What type of PR is this?
/kind bug

What this PR does / why we need it:
Fix a race condition where the FullyApplied condition and AggregatedStatus of a ResourceBinding or ClusterResourceBinding can become stale when a
status update conflicts and retries.

Previously, GetWorksByBindingID and assembleWorkStatus were called once before the RetryOnConflict loop. If the update failed due to a conflict (e.g., the scheduler concurrently updated Spec.Clusters), the retry loop would re-fetch the binding object but still apply a stale status snapshot, potentially setting FullyApplied=True even though new target clusters had been added but their Work objects were not yet applied.

The fix moves work fetching and status assembly inside the UpdateStatus mutation callback, ensuring that on every retry attempt, the status is computed from the latest binding spec and current work objects.

Which issue(s) this PR fixes:

Fixes #7227

Special notes for your reviewer:

A new unit test TestAggregateResourceBindingWorkStatusRetryOnConflict has been added that simulates a concurrent scheduler update (adding a second target cluster) during a conflict retry, and verifies that FullyApplied is correctly set toFalse after the retry.

Also fixed the cleanup() function in hack/update-codegen.sh to run chmod -R u+w before rm -rf so the read-only Go toolchain cache files created in _go/ are properly cleaned up.

Does this PR introduce a user-facing change?:

`karmada-controller-manager`: Fixed the issue that the `FullyApplied` condition
of `ResourceBinding`/`ClusterResourceBinding` could be stale after a concurrent
update conflict during status reconciliation.

Signed-off-by: Varsha <varsha@Varshas-MacBook-Pro.local>
Copilot AI review requested due to automatic review settings June 30, 2026 16:23
@karmada-bot karmada-bot added the kind/bug Categorizes issue or PR as related to a bug. label Jun 30, 2026
@karmada-bot

Copy link
Copy Markdown
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 assign mrlihanbo, xishanyongye-chang for approval. 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

@karmada-bot karmada-bot requested a review from lfbear June 30, 2026 16:23
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, 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 addresses a race condition in the Karmada controller manager where the status of ResourceBinding and ClusterResourceBinding objects could become stale during reconciliation retries. By relocating the status calculation logic into the retry loop, the system now guarantees that status updates are based on the latest state, ensuring accuracy even when concurrent modifications occur. Additionally, the PR includes a robust unit test to validate this behavior and improves the reliability of the codegen cleanup script.

Highlights

  • Race Condition Fix: Moved work fetching and status assembly logic inside the RetryOnConflict loop to ensure status is calculated using the most recent binding specification during retries.
  • Improved Testing: Added a new unit test, TestAggregateResourceBindingWorkStatusRetryOnConflict, to simulate concurrent updates and verify correct status reconciliation during conflict retries.
  • Build Script Cleanup: Updated hack/update-codegen.sh to properly handle file permissions during cleanup, preventing issues with read-only Go toolchain cache files.
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 the 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 counterproductive. 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.

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.

@karmada-bot karmada-bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jun 30, 2026

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

Copy link
Copy Markdown

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 refactors the work status aggregation logic in pkg/util/helper/workstatus.go by moving the retrieval and assembly of work statuses inside the retry.RetryOnConflict block. This ensures that retries operate on the most up-to-date work status data in case of conflicts. Additionally, a new unit test was added to verify this retry behavior under conflict conditions, and a minor permission fix was applied to the codegen cleanup script. The review feedback requests adding compile-time interface compliance checks for the newly introduced test helper structs (conflictFakeClient and conflictFakeStatusWriter) to align with the repository's style guide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

}
}

type conflictFakeClient struct {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

According to the repository style guide, any struct that explicitly implements an interface must include a compile-time interface compliance check using the pattern var _ InterfaceName = &StructName{}. Please add this check for conflictFakeClient.

Suggested change
type conflictFakeClient struct {
var _ client.Client = &conflictFakeClient{}
type conflictFakeClient struct {
References
  1. Any struct that explicitly implements an interface must include a compile-time interface compliance check using the pattern: var _ InterfaceName = &StructName{} (link)

}
}

type conflictFakeStatusWriter struct {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

According to the repository style guide, any struct that explicitly implements an interface must include a compile-time interface compliance check using the pattern var _ InterfaceName = &StructName{}. Please add this check for conflictFakeStatusWriter.

Suggested change
type conflictFakeStatusWriter struct {
var _ client.SubResourceWriter = &conflictFakeStatusWriter{}
type conflictFakeStatusWriter struct {
References
  1. Any struct that explicitly implements an interface must include a compile-time interface compliance check using the pattern: var _ InterfaceName = &StructName{} (link)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a conflict-retry race in AggregateResourceBindingWorkStatus / AggregateClusterResourceBindingWorkStatus where FullyApplied and AggregatedStatus could be computed from a stale snapshot when Status().Update() hit a conflict and retried. It also improves the codegen cleanup script to better handle read-only files under _go/.

Changes:

  • Recomputes the Work list and aggregated status inside the UpdateStatus mutate callback that runs within RetryOnConflict, ensuring each retry uses the latest binding spec and current Works.
  • Adds a unit test that simulates a conflict + concurrent spec update (scheduler adding a new target cluster) and asserts FullyApplied=False after retry.
  • Updates hack/update-codegen.sh cleanup to chmod -R u+w before removing _go/, avoiding failures on read-only cache artifacts.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
pkg/util/helper/workstatus.go Moves work fetching/status assembly into the retry mutation to avoid stale FullyApplied/AggregatedStatus on conflict retries.
pkg/util/helper/workstatus_test.go Adds a conflict-retry unit test via a fake client status-writer wrapper to validate the race condition fix.
hack/update-codegen.sh Ensures _go/ cleanup can delete read-only toolchain/cache files by making them user-writable first.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov-commenter

Copy link
Copy Markdown

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

Codecov Report

❌ Patch coverage is 42.85714% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 42.05%. Comparing base (56d5d87) to head (1adc47d).
⚠️ Report is 12 commits behind head on master.

Files with missing lines Patch % Lines
pkg/util/helper/workstatus.go 42.85% 4 Missing and 4 partials ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7694      +/-   ##
==========================================
- Coverage   42.06%   42.05%   -0.02%     
==========================================
  Files         879      879              
  Lines       54831    54831              
==========================================
- Hits        23063    23057       -6     
- Misses      30023    30028       +5     
- Partials     1745     1746       +1     
Flag Coverage Δ
unittests 42.05% <42.85%> (-0.02%) ⬇️

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

☔ View full report in Codecov by Harness.
📢 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.

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. 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.

Stale FullyApplied condition during RetryOnConflict

4 participants