Skip to content

Commit cdb5e66

Browse files
committed
feat: implement non-blocking CRD reconciliation with requeue support
Implement non blocking CRD reconciliation to improve controller throughput when managing large amount of RGDs. The main idea is to free the workers to do other tasks when we're waiting for the establishement. Previously, the controller would block waiting for CRDs to become established, preventing other ResourceGraphDefinitions from being processed. This change introduces a requeue based approach where: - CRD creation happens immediately without blocking - controller checks CRD establishment status on each reconciliation - if CRD exists but isn't established, reconciler requeues after 500ms - other RGDs can be processed while waiting for CRD establishment this patch also gets rid of the CRDWraper abstraction layer as it's no longer needed.
1 parent d537f9c commit cdb5e66

File tree

10 files changed

+106
-227
lines changed

10 files changed

+106
-227
lines changed

pkg/client/crd.go

Lines changed: 0 additions & 197 deletions
This file was deleted.

pkg/client/fake/fake.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,8 @@ func (f *FakeSet) RESTConfig() *rest.Config {
6666
}
6767

6868
// CRD returns a new CRD interface instance
69-
func (f *FakeSet) CRD(cfg client.CRDWrapperConfig) client.CRDInterface {
70-
// Return a fake CRD implementation for testing
71-
return &FakeCRD{}
69+
func (f *FakeSet) CRD() apiextensionsv1.CustomResourceDefinitionInterface {
70+
return f.ApiExtensionsClient.CustomResourceDefinitions()
7271
}
7372

7473
// WithImpersonation returns a new client that impersonates the given user
@@ -88,10 +87,8 @@ func (f *FakeSet) SetRESTMapper(restMapper meta.RESTMapper) {
8887
// FakeCRD is a fake implementation of CRDInterface for testing
8988
type FakeCRD struct{}
9089

91-
var _ client.CRDInterface = (*FakeCRD)(nil)
92-
93-
// Ensure ensures a CRD exists, up-to-date, and is ready
94-
func (f *FakeCRD) Ensure(ctx context.Context, crd v1.CustomResourceDefinition) error {
90+
// Create ensures a CRD exists, up-to-date, and is ready
91+
func (f *FakeCRD) Create(ctx context.Context, crd v1.CustomResourceDefinition) error {
9592
// For testing, just return success
9693
return nil
9794
}

pkg/client/set.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ type SetInterface interface {
4141
// RESTConfig returns a copy of the underlying REST config
4242
RESTConfig() *rest.Config
4343

44-
// CRD returns a new CRDInterface instance
45-
CRD(cfg CRDWrapperConfig) CRDInterface
44+
// CRD returns a new CustomResourceDefinitionInterface instance
45+
CRD() apiextensionsv1.CustomResourceDefinitionInterface
4646

4747
// WithImpersonation returns a new client that impersonates the given user
4848
WithImpersonation(user string) (SetInterface, error)
@@ -159,13 +159,9 @@ func (c *Set) RESTMapper() meta.RESTMapper {
159159
return c.restMapper
160160
}
161161

162-
// CRD returns a new CRDInterface instance
163-
func (c *Set) CRD(cfg CRDWrapperConfig) CRDInterface {
164-
if cfg.Client == nil {
165-
cfg.Client = c.apiExtensionsV1
166-
}
167-
168-
return newCRDWrapper(cfg)
162+
// CRD returns a new CustomResourceDefinitionInterface instance
163+
func (c *Set) CRD() apiextensionsv1.CustomResourceDefinitionInterface {
164+
return c.apiExtensionsV1.CustomResourceDefinitions()
169165
}
170166

171167
// WithImpersonation returns a new client that impersonates the given user

pkg/controller/resourcegraphdefinition/controller.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/kubernetes-sigs/kro/pkg/dynamiccontroller"
3636
"github.com/kubernetes-sigs/kro/pkg/graph"
3737
"github.com/kubernetes-sigs/kro/pkg/metadata"
38+
"github.com/kubernetes-sigs/kro/pkg/requeue"
3839
)
3940

4041
//+kubebuilder:rbac:groups=kro.run,resources=resourcegraphdefinitions,verbs=get;list;watch;create;update;patch;delete
@@ -51,8 +52,7 @@ type ResourceGraphDefinitionReconciler struct {
5152

5253
instanceLogger logr.Logger
5354

54-
clientSet kroclient.SetInterface
55-
crdManager kroclient.CRDClient
55+
clientSet kroclient.SetInterface
5656

5757
metadataLabeler metadata.Labeler
5858
rgBuilder *graph.Builder
@@ -67,12 +67,10 @@ func NewResourceGraphDefinitionReconciler(
6767
builder *graph.Builder,
6868
maxConcurrentReconciles int,
6969
) *ResourceGraphDefinitionReconciler {
70-
crdWrapper := clientSet.CRD(kroclient.CRDWrapperConfig{})
7170

7271
return &ResourceGraphDefinitionReconciler{
7372
clientSet: clientSet,
7473
allowCRDDeletion: allowCRDDeletion,
75-
crdManager: crdWrapper,
7674
dynamicController: dynamicController,
7775
metadataLabeler: metadata.NewKROMetaLabeler(),
7876
rgBuilder: builder,
@@ -171,9 +169,15 @@ func (r *ResourceGraphDefinitionReconciler) Reconcile(ctx context.Context, o *v1
171169

172170
topologicalOrder, resourcesInformation, reconcileErr := r.reconcileResourceGraphDefinition(ctx, o)
173171

172+
// Always update status
174173
if err := r.updateStatus(ctx, o, topologicalOrder, resourcesInformation); err != nil {
175174
reconcileErr = errors.Join(reconcileErr, err)
176175
}
177176

177+
// Check if this is a requeue error
178+
if needRequeue, duration := requeue.Check(reconcileErr); needRequeue {
179+
return ctrl.Result{RequeueAfter: duration}, nil
180+
}
181+
178182
return ctrl.Result{}, reconcileErr
179183
}

pkg/controller/resourcegraphdefinition/controller_cleanup.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (r *ResourceGraphDefinitionReconciler) cleanupResourceGraphDefinitionCRD(ct
7070
return nil
7171
}
7272

73-
if err := r.crdManager.Delete(ctx, crdName); err != nil {
73+
if err := r.deleteCRD(ctx, crdName); err != nil {
7474
return fmt.Errorf("error deleting CRD: %w", err)
7575
}
7676
return nil

0 commit comments

Comments
 (0)