diff --git a/webhosting-operator/pkg/experiment/generator/reconciler.go b/webhosting-operator/pkg/experiment/generator/reconciler.go index 916d8d01..bd187ceb 100644 --- a/webhosting-operator/pkg/experiment/generator/reconciler.go +++ b/webhosting-operator/pkg/experiment/generator/reconciler.go @@ -33,6 +33,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/predicate" + "sigs.k8s.io/controller-runtime/pkg/ratelimiter" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -79,7 +80,6 @@ type ForEach[T client.Object] struct { Name string Do func(ctx context.Context, c client.Client, obj T) error Every time.Duration - RateLimit rate.Limit Stop time.Time gvk schema.GroupVersionKind @@ -91,11 +91,6 @@ func (r *ForEach[T]) AddToManager(mgr manager.Manager) error { r.Client = mgr.GetClient() } - rateLimiter := workqueue.DefaultControllerRateLimiter() - if r.RateLimit > 0 { - rateLimiter = &workqueue.BucketRateLimiter{Limiter: rate.NewLimiter(r.RateLimit, int(r.RateLimit))} - } - var t T r.obj = reflect.New(reflect.TypeOf(t).Elem()).Interface().(T) @@ -109,7 +104,7 @@ func (r *ForEach[T]) AddToManager(mgr manager.Manager) error { Named(r.Name). WithOptions(controller.Options{ MaxConcurrentReconciles: reconcileWorkers, - RateLimiter: rateLimiter, + RateLimiter: unlimitedRateLimiter(), }). Watches( r.obj, @@ -140,3 +135,9 @@ func (r *ForEach[T]) Reconcile(ctx context.Context, request reconcile.Request) ( return reconcile.Result{RequeueAfter: r.Every}, r.Do(ctx, r.Client, obj) } + +// unlimitedRateLimiter returns a RateLimiter that doesn't apply any rate limits to the workqueue. +func unlimitedRateLimiter() ratelimiter.RateLimiter { + // if no limiter is given, MaxOfRateLimiter returns 0 for When and NumRequeues => unlimited + return &workqueue.MaxOfRateLimiter{} +} diff --git a/webhosting-operator/pkg/experiment/scenario/basic/basic.go b/webhosting-operator/pkg/experiment/scenario/basic/basic.go index b5523757..1d344dbf 100644 --- a/webhosting-operator/pkg/experiment/scenario/basic/basic.go +++ b/webhosting-operator/pkg/experiment/scenario/basic/basic.go @@ -54,7 +54,7 @@ func (s *scenario) LongDescription() string { return `The ` + ScenarioName + ` scenario combines several operations typical for a lively operator environment: - website creation: 8000 over 10m - website deletion: 600 over 10m -- website reconciliation: max 100/s +- website reconciliation: max 130/s - theme reconciliation: 1/m -> triggers reconciliation of all referencing websites ` } @@ -99,18 +99,18 @@ func (s *scenario) Run(ctx context.Context) error { return fmt.Errorf("error adding website-deleter: %w", err) } - // trigger individual reconciliations for website twice per minute, 100 per second at max + // trigger individual reconciliations for website once per minute + // => peaks at about 130 reconciliations per second if err := (&generator.ForEach[*webhostingv1alpha1.Website]{ - Name: "website-mutator", - Do: generator.ReconcileWebsite, - Every: time.Minute, - RateLimit: rate.Limit(100), + Name: "website-mutator", + Do: generator.ReconcileWebsite, + Every: time.Minute, }).AddToManager(s.Manager); err != nil { return fmt.Errorf("error adding website-mutator: %w", err) } // update one theme every minute which causes all referencing websites to be reconciled - // => peeks at about 2.6 reconciliations per second on average + // => peaks at about 2.6 reconciliations per second on average // (note: these reconciliation triggers occur in bursts of up to ~156) if err := (&generator.Every{ Name: "theme-mutator",