Skip to content

Bugfix: an incomplete list response must not delete cached objects - #2746

Open
Rad710 wants to merge 1 commit into
openyurtio:masterfrom
Rad710:fix-incomplete-list-truncates-cache
Open

Bugfix: an incomplete list response must not delete cached objects#2746
Rad710 wants to merge 1 commit into
openyurtio:masterfrom
Rad710:fix-incomplete-list-truncates-cache

Conversation

@Rad710

@Rad710 Rad710 commented Aug 11, 2026

Copy link
Copy Markdown

What type of PR is this?

/kind bug

What this PR does / why we need it:

saveListObject routed every multi-object list response into ReplaceComponentList, which deletes every cached object of that type that is absent from the response — i.e. it treats the response as the complete, authoritative list. Two common list shapes carry only a subset, so this silently truncated the cache:

  • An empty ?fieldSelector=metadata.name=<x> list (the named object does not exist) deleted the whole cached collection for that type.
  • Any page of a paginated list carries only that page, so each page deleted the objects on the other pages. The last page is indistinguishable from a complete list by its response alone (the continue token is empty either way), so only the request reveals it.

This routes those shapes to a no-delete merge path that writes the carried objects and prunes nothing. A genuinely complete list (an informer relist with no name selector, no pagination and no resourceVersionMatch=Exact) still prunes, as before.

Trade-off worth stating: a component that always paginates now keeps objects that were deleted in the cloud while yurthub was disconnected (GC still collects pods and events). Serving a stale-but-complete cached view is preferable to handing a truncated collection to a consumer.

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

New cache_truncation_test.go covers the empty name-selector wipe, odd name-selector values, first/last page pagination, a cold cache, point-in-time lists, and TestCompleteListStillPrunes (a genuinely complete list must still prune). Each fails on the current code and passes with the fix.

Does this PR introduce a user-facing change?

Stop yurthub from deleting cached objects when it receives an incomplete list response (an empty metadata.name field-selector list, or a page of a paginated list).

saveListObject routed every multi-object list into ReplaceComponentList, which deletes cached objects absent from the response. But a ?fieldSelector=metadata.name= list or a single page of a paginated list carries only a subset: an empty name-selector response wiped the whole cached collection, and one page deleted the objects on the other pages.

Route these to a no-delete merge path. A genuinely complete list still prunes (TestCompleteListStillPrunes). Trade-off: an always-paginating component keeps objects deleted in the cloud while disconnected, which beats serving a truncated collection after an offline reboot.

Signed-off-by: Rolando Medina Rosner <rolmedro@gmail.com>
@Rad710
Rad710 requested a review from a team as a code owner August 11, 2026 19:30
@sonarqubecloud

Copy link
Copy Markdown

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant