Skip to content

Commit 24e0b8d

Browse files
authored
Use APIReader for reading desired object directly from k8s apiserver (#49)
Issue #, if available: aws-controllers-k8s/community#894 Description of changes: * Use `APIReader` for making reading desired state of k8s resource directly from apiserver and avoid any client caches. Also see: kubernetes-sigs/controller-runtime#585 (comment) Tested locally with apigatewayv2 controller and this change resolves the duplicate API creation issue. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 8665453 commit 24e0b8d

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

pkg/runtime/reconciler.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,13 @@ import (
4040

4141
// reconciler describes a generic reconciler within ACK.
4242
type reconciler struct {
43-
sc acktypes.ServiceController
44-
kc client.Client
45-
log logr.Logger
46-
cfg ackcfg.Config
47-
cache ackrtcache.Caches
48-
metrics *ackmetrics.Metrics
43+
sc acktypes.ServiceController
44+
kc client.Client
45+
apiReader client.Reader
46+
log logr.Logger
47+
cfg ackcfg.Config
48+
cache ackrtcache.Caches
49+
metrics *ackmetrics.Metrics
4950
}
5051

5152
// resourceReconciler is responsible for reconciling the state of a SINGLE KIND of
@@ -77,6 +78,7 @@ func (r *resourceReconciler) BindControllerManager(mgr ctrlrt.Manager) error {
7778
return ackerr.NilResourceManagerFactory
7879
}
7980
r.kc = mgr.GetClient()
81+
r.apiReader = mgr.GetAPIReader()
8082
rd := r.rmf.ResourceDescriptor()
8183
return ctrlrt.NewControllerManagedBy(
8284
mgr,
@@ -574,12 +576,24 @@ func (r *resourceReconciler) failOnResourceUnmanaged(
574576

575577
// getAWSResource returns an AWSResource representing the requested Kubernetes
576578
// namespaced object
579+
// NOTE: this method makes direct call to k8s apiserver. Currently this method
580+
// is only invoked once per reconciler loop. For future use, Take care of k8s
581+
// apiserver rate limit if calling this method more than once per reconciler
582+
// loop.
577583
func (r *resourceReconciler) getAWSResource(
578584
ctx context.Context,
579585
req ctrlrt.Request,
580586
) (acktypes.AWSResource, error) {
581587
ro := r.rd.EmptyRuntimeObject()
582-
if err := r.kc.Get(ctx, req.NamespacedName, ro); err != nil {
588+
// Here we use k8s APIReader to read the k8s object by making the
589+
// direct call to k8s apiserver instead of using k8sClient.
590+
// The reason is that k8sClient uses a cache and sometimes k8sClient can
591+
// return stale copy of object.
592+
// It is okay to make direct call to k8s apiserver because we are only
593+
// making single read call for complete reconciler loop.
594+
// See following issue for more details:
595+
// https://github.com/aws-controllers-k8s/community/issues/894
596+
if err := r.apiReader.Get(ctx, req.NamespacedName, ro); err != nil {
583597
return nil, err
584598
}
585599
return r.rd.ResourceFromRuntimeObject(ro), nil

0 commit comments

Comments
 (0)