Skip to content

Commit 581f85e

Browse files
committed
nrr: Refactor r.List() to call only once.
Previously, several child functions were calling "r.List()" duplicating work. This commit address the issue. Now we call it "r.List()" once in "reconcile()" parent functions. This commit aims to reduce memory allocs and improve memory optimization. Signed-off-by: Sujal Shah <sujalshah28092004@gmail.com>
1 parent 6d4dd7b commit 581f85e

1 file changed

Lines changed: 22 additions & 41 deletions

File tree

internal/controller/nodereadinessrule_controller.go

Lines changed: 22 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,21 @@ func (r *RuleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
120120
return ctrl.Result{RequeueAfter: time.Second}, nil
121121
}
122122

123+
nodeList := &corev1.NodeList{}
124+
if err := r.List(ctx, nodeList); err != nil {
125+
return ctrl.Result{}, err
126+
}
127+
123128
// Handle deletion reconciliation loop.
124129
if !rule.DeletionTimestamp.IsZero() {
125-
return r.reconcileDelete(ctx, rule)
130+
return r.reconcileDelete(ctx, rule, nodeList)
126131
}
127132

128133
// Detect nodeSelector changes and cleanup old nodes
129134
cachedRule := r.Controller.getCachedRule(rule.Name)
130135
if cachedRule != nil && nodeSelectorChanged(rule.Spec.NodeSelector, cachedRule.Spec.NodeSelector) {
131136
log.Info("NodeSelector changed, cleaning up nodes from old selector", "rule", rule.Name)
132-
if err := r.Controller.cleanupNodesAfterSelectorChange(ctx, cachedRule, rule); err != nil {
137+
if err := r.Controller.cleanupNodesAfterSelectorChange(ctx, cachedRule, rule, nodeList); err != nil {
133138
log.Error(err, "Failed to cleanup nodes after selector change", "rule", rule.Name)
134139
return ctrl.Result{RequeueAfter: time.Minute}, err
135140
}
@@ -140,7 +145,7 @@ func (r *RuleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
140145

141146
// Handle dry run
142147
if rule.Spec.DryRun {
143-
if err := r.Controller.processDryRun(ctx, rule); err != nil {
148+
if err := r.Controller.processDryRun(ctx, rule, nodeList); err != nil {
144149
log.Error(err, "Failed to process dry run", "rule", rule.Name)
145150
return ctrl.Result{RequeueAfter: time.Minute}, err
146151
}
@@ -149,7 +154,7 @@ func (r *RuleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
149154
rule.Status.DryRunResults = readinessv1alpha1.DryRunResults{}
150155

151156
// Process all applicable nodes for this rule
152-
if err := r.Controller.processAllNodesForRule(ctx, rule); err != nil {
157+
if err := r.Controller.processAllNodesForRule(ctx, rule, nodeList); err != nil {
153158
log.Error(err, "Failed to process nodes for rule", "rule", rule.Name)
154159
return ctrl.Result{RequeueAfter: time.Minute}, err
155160
}
@@ -162,7 +167,7 @@ func (r *RuleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
162167
}
163168

164169
// Clean up status for deleted nodes
165-
if err := r.Controller.cleanupDeletedNodes(ctx, rule); err != nil {
170+
if err := r.Controller.cleanupDeletedNodes(ctx, rule, nodeList); err != nil {
166171
log.Error(err, "Failed to clean up deleted nodes", "rule", rule.Name)
167172
return ctrl.Result{RequeueAfter: time.Minute}, err
168173
}
@@ -174,15 +179,15 @@ func (r *RuleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
174179
// 1. Deletes the taints associated with the rule.
175180
// 2. Remove the rule from the cache.
176181
// 3. Remove the finalizer from the rule.
177-
func (r *RuleReconciler) reconcileDelete(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule) (ctrl.Result, error) {
182+
func (r *RuleReconciler) reconcileDelete(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule, nodeList *corev1.NodeList) (ctrl.Result, error) {
178183
log := ctrl.LoggerFrom(ctx)
179184

180185
// Update cache with deletion-marked rule before cleanup.
181186
log.V(3).Info("Updating cache with deletion-marked rule before cleanup")
182187
r.Controller.updateRuleCache(ctx, rule)
183188

184189
log.Info("Cleaning up taints for deleted rule", "rule", rule.Name)
185-
if err := r.Controller.cleanupTaintsForRule(ctx, rule); err != nil {
190+
if err := r.Controller.cleanupTaintsForRule(ctx, rule, nodeList); err != nil {
186191
log.Error(err, "Failed to cleanup taints for rule", "rule", rule.Name)
187192
return ctrl.Result{RequeueAfter: time.Minute}, err
188193
}
@@ -201,15 +206,10 @@ func (r *RuleReconciler) reconcileDelete(ctx context.Context, rule *readinessv1a
201206
}
202207

203208
// cleanupDeletedNodes removes status entries for nodes that no longer exist.
204-
func (r *RuleReadinessController) cleanupDeletedNodes(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule) error {
209+
func (r *RuleReadinessController) cleanupDeletedNodes(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule, nodeList *corev1.NodeList) error {
205210
log := ctrl.LoggerFrom(ctx)
206211

207-
nodeList := &corev1.NodeList{}
208-
if err := r.List(ctx, nodeList); err != nil {
209-
return err
210-
}
211-
212-
existingNodes := make(map[string]bool)
212+
existingNodes := make(map[string]bool, len(nodeList.Items))
213213
for _, node := range nodeList.Items {
214214
existingNodes[node.Name] = true
215215
}
@@ -257,14 +257,11 @@ func (r *RuleReadinessController) cleanupDeletedNodes(ctx context.Context, rule
257257
}
258258

259259
// processAllNodesForRule processes all nodes when a rule changes.
260-
func (r *RuleReadinessController) processAllNodesForRule(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule) error {
260+
//
261+
//nolint:unparam // Keep error return for future extensibility and API stability.
262+
func (r *RuleReadinessController) processAllNodesForRule(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule, nodeList *corev1.NodeList) error {
261263
log := ctrl.LoggerFrom(ctx)
262264

263-
nodeList := &corev1.NodeList{}
264-
if err := r.List(ctx, nodeList); err != nil {
265-
return err
266-
}
267-
268265
log.Info("Processing all nodes for rule", "rule", rule.Name, "totalNodes", len(nodeList.Items))
269266

270267
var appliedNodes []string
@@ -516,12 +513,9 @@ func (r *RuleReadinessController) updateRuleStatus(ctx context.Context, rule *re
516513
}
517514

518515
// processDryRun processes dry run for a rule.
519-
func (r *RuleReadinessController) processDryRun(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule) error {
520-
nodeList := &corev1.NodeList{}
521-
if err := r.List(ctx, nodeList); err != nil {
522-
return err
523-
}
524-
516+
//
517+
//nolint:unparam // Keep error return for future extensibility and API stability.
518+
func (r *RuleReadinessController) processDryRun(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule, nodeList *corev1.NodeList) error {
525519
var affectedNodes, taintsToAdd, taintsToRemove, riskyOps int32
526520
var summaryParts []string
527521

@@ -585,20 +579,13 @@ func (r *RuleReadinessController) processDryRun(ctx context.Context, rule *readi
585579
RiskyOperations: &riskyOps,
586580
Summary: summary,
587581
}
588-
589582
return nil
590583
}
591584

592585
// cleanupTaintsForRule removes taints managed by this rule from all applicable nodes.
593-
func (r *RuleReadinessController) cleanupTaintsForRule(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule) error {
586+
func (r *RuleReadinessController) cleanupTaintsForRule(ctx context.Context, rule *readinessv1alpha1.NodeReadinessRule, nodeList *corev1.NodeList) error {
594587
log := ctrl.LoggerFrom(ctx)
595588

596-
// Get all nodes that this rule applies to
597-
nodeList := &corev1.NodeList{}
598-
if err := r.List(ctx, nodeList); err != nil {
599-
return fmt.Errorf("failed to list nodes: %w", err)
600-
}
601-
602589
var errors []string
603590
for _, node := range nodeList.Items {
604591
if !r.ruleAppliesTo(ctx, rule, &node) {
@@ -626,15 +613,9 @@ func (r *RuleReadinessController) cleanupTaintsForRule(ctx context.Context, rule
626613
}
627614

628615
// cleanupNodesAfterSelectorChange cleans up nodes that matched old selector but not new one.
629-
func (r *RuleReadinessController) cleanupNodesAfterSelectorChange(ctx context.Context, oldRule, newRule *readinessv1alpha1.NodeReadinessRule) error {
616+
func (r *RuleReadinessController) cleanupNodesAfterSelectorChange(ctx context.Context, oldRule, newRule *readinessv1alpha1.NodeReadinessRule, nodeList *corev1.NodeList) error {
630617
log := ctrl.LoggerFrom(ctx)
631618

632-
// Get all nodes
633-
nodeList := &corev1.NodeList{}
634-
if err := r.List(ctx, nodeList); err != nil {
635-
return fmt.Errorf("failed to list nodes: %w", err)
636-
}
637-
638619
// Build old selector
639620
oldSelector, err := metav1.LabelSelectorAsSelector(&oldRule.Spec.NodeSelector)
640621
if err != nil {

0 commit comments

Comments
 (0)