Skip to content

Commit 3e870eb

Browse files
authored
🐛 Start the Cache if the Manager has already started (#1681)
* Start the Cache if the Manager has already started * verify adding cluster after mgr started results in working cache Add a test that adds a cluster to the manager after the manager has already started. Verify that the cluster is started and its cache is sycned. Added the startClusterAfterManager struct which is a basically just a hook to verify that the cluster is started. * remove unnecessary methods Only GetCache and Start methods are neeed for new test that adds a cluster to the manage after the manager has already started.
1 parent e1880f5 commit 3e870eb

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

pkg/manager/internal.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,12 @@ func (cm *controllerManager) Add(r Runnable) error {
211211
cm.nonLeaderElectionRunnables = append(cm.nonLeaderElectionRunnables, r)
212212
} else if hasCache, ok := r.(hasCache); ok {
213213
cm.caches = append(cm.caches, hasCache)
214+
if cm.started {
215+
cm.startRunnable(hasCache)
216+
if !hasCache.GetCache().WaitForCacheSync(cm.internalCtx) {
217+
return fmt.Errorf("could not sync cache")
218+
}
219+
}
214220
} else {
215221
shouldStart = cm.startedLeader
216222
cm.leaderElectionRunnables = append(cm.leaderElectionRunnables, r)

pkg/manager/manager_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,46 @@ var _ = Describe("manger.Manager", func() {
765765
Expect(err.Error()).To(Equal("expected error"))
766766
})
767767

768+
It("should start caches added after Manager has started", func() {
769+
fakeCache := &startSignalingInformer{Cache: &informertest.FakeInformers{}}
770+
options.NewCache = func(_ *rest.Config, _ cache.Options) (cache.Cache, error) {
771+
return fakeCache, nil
772+
}
773+
m, err := New(cfg, options)
774+
Expect(err).NotTo(HaveOccurred())
775+
for _, cb := range callbacks {
776+
cb(m)
777+
}
778+
779+
runnableWasStarted := make(chan struct{})
780+
Expect(m.Add(RunnableFunc(func(ctx context.Context) error {
781+
defer GinkgoRecover()
782+
if !fakeCache.wasSynced {
783+
return errors.New("WaitForCacheSyncCalled wasn't called before Runnable got started")
784+
}
785+
close(runnableWasStarted)
786+
return nil
787+
}))).To(Succeed())
788+
789+
ctx, cancel := context.WithCancel(context.Background())
790+
defer cancel()
791+
go func() {
792+
defer GinkgoRecover()
793+
Expect(m.Start(ctx)).ToNot(HaveOccurred())
794+
}()
795+
796+
<-runnableWasStarted
797+
798+
additionalClusterCache := &startSignalingInformer{Cache: &informertest.FakeInformers{}}
799+
fakeCluster := &startClusterAfterManager{informer: additionalClusterCache}
800+
801+
Expect(err).NotTo(HaveOccurred())
802+
Expect(m.Add(fakeCluster)).NotTo(HaveOccurred())
803+
804+
Expect(fakeCluster.informer.wasStarted).To(BeTrue())
805+
Expect(fakeCluster.informer.wasSynced).To(BeTrue())
806+
})
807+
768808
It("should wait for runnables to stop", func() {
769809
m, err := New(cfg, options)
770810
Expect(err).NotTo(HaveOccurred())
@@ -1758,3 +1798,15 @@ func (c *startSignalingInformer) WaitForCacheSync(ctx context.Context) bool {
17581798
}()
17591799
return c.Cache.WaitForCacheSync(ctx)
17601800
}
1801+
1802+
type startClusterAfterManager struct {
1803+
informer *startSignalingInformer
1804+
}
1805+
1806+
func (c *startClusterAfterManager) Start(ctx context.Context) error {
1807+
return c.informer.Start(ctx)
1808+
}
1809+
1810+
func (c *startClusterAfterManager) GetCache() cache.Cache {
1811+
return c.informer
1812+
}

0 commit comments

Comments
 (0)