Skip to content

target: cache compiled LabelSelector per ClusterGroup to reduce CPU#5445

Open
himabindugit wants to merge 3 commits into
rancher:mainfrom
himabindugit:fix/cache-label-selector-v2
Open

target: cache compiled LabelSelector per ClusterGroup to reduce CPU#5445
himabindugit wants to merge 3 commits into
rancher:mainfrom
himabindugit:fix/cache-label-selector-v2

Conversation

@himabindugit

@himabindugit himabindugit commented Jul 15, 2026

Copy link
Copy Markdown

#5444
Refers to #5444

Problem

clusterGroupsForCluster calls metav1.LabelSelectorAsSelector on every reconcile loop for every ClusterGroup, with no caching. At scale this causes an allocation storm.

With ~3900 clusters × 10 ClusterGroups: 39,130 LabelSelectorAsSelector compilations per OnBundleChange event. pprof showed LabelSelectorAsSelector consuming 61% CPU on the fleet-controller, leading to OOM and lease-lock failures.

Reported in: #5444

Fix

Cache the compiled labels.Selector in a sync.Map on the Manager, keyed by namespace/name@resourceVersion. The ResourceVersion ensures the selector is recompiled when a ClusterGroup is updated.

ClusterGroups change infrequently and their count is small, so stale entries from old ResourceVersions are acceptable and not evicted.

Added unit tests covering:

  • Matching and non-matching selectors
  • Nil selector skipped
  • Invalid selector not cached
  • Cache populated after first call
  • New ResourceVersion gets a new cache entry

Additional Information

Checklist

  • I have updated the documentation via a pull request in the fleet-product-docs repository.

Copilot AI review requested due to automatic review settings July 15, 2026 05:18
@himabindugit himabindugit requested a review from a team as a code owner July 15, 2026 05:18

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 optimizes target selection by caching compiled Kubernetes LabelSelector objects per ClusterGroup (keyed by namespace/name@resourceVersion) to reduce repeated metav1.LabelSelectorAsSelector compilations during reconcile loops.

Changes:

  • Implement per-Manager selector compilation caching via sync.Map in clusterGroupsForCluster.
  • Add unit tests for selector matching behavior and caching behavior.
  • Extend the target.Manager struct to hold the selector cache.

Reviewed changes

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

File Description
internal/cmd/controller/target/query.go Adds selector caching in clusterGroupsForCluster to reduce CPU/allocations during target queries.
internal/cmd/controller/target/query_test.go Adds unit tests for selector matching/caching behavior.
internal/cmd/controller/target/builder.go Adds a sync.Map field to Manager to store the selector cache.

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

Comment thread internal/cmd/controller/target/query.go
Comment thread internal/cmd/controller/target/query_test.go
himabindugit and others added 2 commits July 15, 2026 01:25
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

3 participants