Skip to content

Commit 8fa7dc8

Browse files
reduce unnecessary watch events and bindingSpec change in the binding controller
Signed-off-by: changzhen <[email protected]>
1 parent 70411ab commit 8fa7dc8

File tree

4 files changed

+448
-2
lines changed

4 files changed

+448
-2
lines changed

pkg/controllers/binding/binding_controller.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ import (
3131
"k8s.io/klog/v2"
3232
"k8s.io/utils/ptr"
3333
controllerruntime "sigs.k8s.io/controller-runtime"
34+
"sigs.k8s.io/controller-runtime/pkg/builder"
3435
"sigs.k8s.io/controller-runtime/pkg/client"
3536
"sigs.k8s.io/controller-runtime/pkg/controller"
3637
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
38+
"sigs.k8s.io/controller-runtime/pkg/event"
3739
"sigs.k8s.io/controller-runtime/pkg/handler"
3840
"sigs.k8s.io/controller-runtime/pkg/predicate"
3941
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -185,9 +187,27 @@ func (c *ResourceBindingController) checkDirectPurgeOrphanWorks(ctx context.Cont
185187

186188
// SetupWithManager creates a controller and register to controller manager.
187189
func (c *ResourceBindingController) SetupWithManager(mgr controllerruntime.Manager) error {
190+
bindingPredicateFn := predicate.Funcs{
191+
CreateFunc: func(_ event.CreateEvent) bool {
192+
return true
193+
},
194+
UpdateFunc: func(updateEvent event.UpdateEvent) bool {
195+
oldBinding := updateEvent.ObjectOld.(*workv1alpha2.ResourceBinding)
196+
newBinding := updateEvent.ObjectNew.(*workv1alpha2.ResourceBinding)
197+
return careBindingSpecChanged(oldBinding.Spec, newBinding.Spec)
198+
},
199+
DeleteFunc: func(_ event.DeleteEvent) bool {
200+
// The binding object has a finalizer. When the deletion timestamp is not nil,
201+
// it means the object is being deleted and the controller will handle the
202+
// deletion process, so the delete event can be ignored.
203+
return false
204+
},
205+
GenericFunc: func(_ event.GenericEvent) bool { return false },
206+
}
207+
188208
return controllerruntime.NewControllerManagedBy(mgr).
189209
Named(ControllerName).
190-
For(&workv1alpha2.ResourceBinding{}).
210+
For(&workv1alpha2.ResourceBinding{}, builder.WithPredicates(bindingPredicateFn)).
191211
WithEventFilter(predicate.GenerationChangedPredicate{}).
192212
Watches(&policyv1alpha1.OverridePolicy{}, handler.EnqueueRequestsFromMapFunc(c.newOverridePolicyFunc())).
193213
Watches(&policyv1alpha1.ClusterOverridePolicy{}, handler.EnqueueRequestsFromMapFunc(c.newOverridePolicyFunc())).

pkg/controllers/binding/cluster_resource_binding_controller.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ import (
3131
"k8s.io/klog/v2"
3232
"k8s.io/utils/ptr"
3333
controllerruntime "sigs.k8s.io/controller-runtime"
34+
"sigs.k8s.io/controller-runtime/pkg/builder"
3435
"sigs.k8s.io/controller-runtime/pkg/client"
3536
"sigs.k8s.io/controller-runtime/pkg/controller"
3637
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
38+
"sigs.k8s.io/controller-runtime/pkg/event"
3739
"sigs.k8s.io/controller-runtime/pkg/handler"
3840
"sigs.k8s.io/controller-runtime/pkg/predicate"
3941
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -183,9 +185,26 @@ func (c *ClusterResourceBindingController) checkDirectPurgeOrphanWorks(ctx conte
183185

184186
// SetupWithManager creates a controller and register to controller manager.
185187
func (c *ClusterResourceBindingController) SetupWithManager(mgr controllerruntime.Manager) error {
188+
bindingPredicateFn := predicate.Funcs{
189+
CreateFunc: func(_ event.CreateEvent) bool {
190+
return true
191+
},
192+
UpdateFunc: func(updateEvent event.UpdateEvent) bool {
193+
oldBinding := updateEvent.ObjectOld.(*workv1alpha2.ClusterResourceBinding)
194+
newBinding := updateEvent.ObjectNew.(*workv1alpha2.ClusterResourceBinding)
195+
return careBindingSpecChanged(oldBinding.Spec, newBinding.Spec)
196+
},
197+
DeleteFunc: func(_ event.DeleteEvent) bool {
198+
// The binding object has a finalizer. When the deletion timestamp is not nil,
199+
// it means the object is being deleted and the controller will handle the
200+
// deletion process, so the delete event can be ignored.
201+
return false
202+
},
203+
GenericFunc: func(_ event.GenericEvent) bool { return false },
204+
}
186205
return controllerruntime.NewControllerManagedBy(mgr).
187206
Named(ClusterResourceBindingControllerName).
188-
For(&workv1alpha2.ClusterResourceBinding{}).
207+
For(&workv1alpha2.ClusterResourceBinding{}, builder.WithPredicates(bindingPredicateFn)).
189208
Watches(&policyv1alpha1.ClusterOverridePolicy{}, handler.EnqueueRequestsFromMapFunc(c.newOverridePolicyFunc())).
190209
WithEventFilter(predicate.GenerationChangedPredicate{}).
191210
WithOptions(controller.Options{RateLimiter: ratelimiterflag.DefaultControllerRateLimiter[controllerruntime.Request](c.RateLimiterOptions)}).

pkg/controllers/binding/common.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package binding
1818

1919
import (
2020
"context"
21+
"reflect"
2122
"strconv"
2223
"time"
2324

@@ -354,3 +355,38 @@ func shouldSuspendDispatching(suspension *workv1alpha2.Suspension, targetCluster
354355
}
355356
return suspendDispatching
356357
}
358+
359+
type bindingSpecDigest struct {
360+
Resource workv1alpha2.ObjectReference
361+
Clusters []workv1alpha2.TargetCluster
362+
GracefulEvictionTasks []workv1alpha2.GracefulEvictionTask
363+
RequiredBy []workv1alpha2.BindingSnapshot
364+
ConflictResolution policyv1alpha1.ConflictResolution
365+
Suspension *workv1alpha2.Suspension
366+
PreserveResourcesOnDeletion *bool
367+
}
368+
369+
// careBindingSpecChanged checks whether the fields in bindingSpec that the binding controller cares about have changed.
370+
// This helps avoid triggering the binding controller to resync when irrelevant fields are modified.
371+
func careBindingSpecChanged(oldBindingSpec, newBindingSpec workv1alpha2.ResourceBindingSpec) bool {
372+
oldDigest := bindingSpecDigest{
373+
Resource: oldBindingSpec.Resource,
374+
Clusters: oldBindingSpec.Clusters,
375+
GracefulEvictionTasks: oldBindingSpec.GracefulEvictionTasks,
376+
RequiredBy: oldBindingSpec.RequiredBy,
377+
ConflictResolution: oldBindingSpec.ConflictResolution,
378+
Suspension: oldBindingSpec.Suspension,
379+
PreserveResourcesOnDeletion: oldBindingSpec.PreserveResourcesOnDeletion,
380+
}
381+
newDigest := bindingSpecDigest{
382+
Resource: newBindingSpec.Resource,
383+
Clusters: newBindingSpec.Clusters,
384+
GracefulEvictionTasks: newBindingSpec.GracefulEvictionTasks,
385+
RequiredBy: newBindingSpec.RequiredBy,
386+
ConflictResolution: newBindingSpec.ConflictResolution,
387+
Suspension: newBindingSpec.Suspension,
388+
PreserveResourcesOnDeletion: newBindingSpec.PreserveResourcesOnDeletion,
389+
}
390+
391+
return !reflect.DeepEqual(oldDigest, newDigest)
392+
}

0 commit comments

Comments
 (0)