Skip to content

Commit dda2022

Browse files
authored
Wait for the Namespace and Account informers to sync before controller startup (#154)
Add a new functionality to help waiting for the `Namespace` and `Account` cache informers to sync before proceeding with the creation of the reconcilers. Key changes: - Publish `informer.HasSynced` to the top level structs for namespace and accout caches - Use these `informer.HasSynced` to wait for the caches to sync using `"k8s.io/client-go/tools/cache"`. - We call the wait mechanism right after the function that spins the informers a.k.a `caches.Run`. Last to note, we are using a `context.TODO()` context, as a temporary workaround until we figure out a better mechanism for context cancellation. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent fa6e794 commit dda2022

File tree

5 files changed

+25
-2
lines changed

5 files changed

+25
-2
lines changed

pkg/runtime/cache/account.go

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ type AccountCache struct {
5050
log logr.Logger
5151
roleARNs map[string]string
5252
configMapCreated bool
53+
hasSynced func() bool
5354
}
5455

5556
// NewAccountCache instanciate a new AccountCache.
@@ -111,6 +112,7 @@ func (c *AccountCache) Run(clientSet kubernetes.Interface, stopCh <-chan struct{
111112
},
112113
})
113114
go informer.Run(stopCh)
115+
c.hasSynced = informer.HasSynced
114116
}
115117

116118
// GetAccountRoleARN queries the AWS accountID associated Role ARN

pkg/runtime/cache/cache.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
package cache
1515

1616
import (
17+
"context"
1718
"time"
1819

1920
"github.com/go-logr/logr"
2021
"github.com/jaypipes/envutil"
2122
kubernetes "k8s.io/client-go/kubernetes"
23+
"k8s.io/client-go/tools/cache"
2224
)
2325

2426
const (
@@ -96,7 +98,14 @@ func (c Caches) Run(clientSet kubernetes.Interface) {
9698
if c.Namespaces != nil {
9799
c.Namespaces.Run(clientSet, stopCh)
98100
}
99-
c.stopCh = stopCh
101+
}
102+
103+
// WaitForCachesToSync waits for both of the namespace and configMap
104+
// informers to sync - by checking their hasSynced functions.
105+
func (c Caches) WaitForCachesToSync(ctx context.Context) bool {
106+
namespaceSynced := cache.WaitForCacheSync(ctx.Done(), c.Namespaces.hasSynced)
107+
accountSynced := cache.WaitForCacheSync(ctx.Done(), c.Accounts.hasSynced)
108+
return namespaceSynced && accountSynced
100109
}
101110

102111
// Stop closes the stop channel and cause all the SharedInformers

pkg/runtime/cache/namespace.go

+4
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ type NamespaceCache struct {
8484
watchScope []string
8585
// ignored is the list of namespaces we are ignoring
8686
ignored []string
87+
// hasSynced is a function that will return true if namespace informer
88+
// has received "at least" once the full list of the namespaces.
89+
hasSynced func() bool
8790
}
8891

8992
// NewNamespaceCache instanciate a new NamespaceCache.
@@ -160,6 +163,7 @@ func (c *NamespaceCache) Run(clientSet kubernetes.Interface, stopCh <-chan struc
160163
},
161164
})
162165
go informer.Run(stopCh)
166+
c.hasSynced = informer.HasSynced
163167
}
164168

165169
// GetDefaultRegion returns the default region if it it exists

pkg/runtime/service_controller.go

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package runtime
1515

1616
import (
17+
"context"
1718
"fmt"
1819
"strings"
1920
"sync"
@@ -233,6 +234,10 @@ func (c *serviceController) BindControllerManager(mgr ctrlrt.Manager, cfg ackcfg
233234
// Run the caches. This will not block as the caches are run in
234235
// separate goroutines.
235236
cache.Run(clientSet)
237+
// Wait for the caches to sync
238+
ctx := context.TODO()
239+
synced := cache.WaitForCachesToSync(ctx)
240+
c.log.Info("Waited for the caches to sync", "synced", synced)
236241
}
237242

238243
if cfg.EnableAdoptedResourceReconciler {

pkg/runtime/service_controller_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,10 @@ func TestServiceController(t *testing.T) {
176176
require.Empty(recons)
177177

178178
mgr := &fakeManager{}
179-
cfg := ackcfg.Config{}
179+
cfg := ackcfg.Config{
180+
// Disable caches, by setting a mono-namespace watch mode
181+
WatchNamespace: "default",
182+
}
180183
err := sc.BindControllerManager(mgr, cfg)
181184
require.Nil(err)
182185

0 commit comments

Comments
 (0)