Skip to content

Commit 8c39906

Browse files
authored
Merge pull request kubernetes-sigs#755 from joelanford/fix-cache-race
🐛 wait for cache start before returning from WaitForCacheSync
2 parents 0d78900 + faacf85 commit 8c39906

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

pkg/cache/internal/deleg_map.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,17 @@ func (m *InformersMap) Start(stop <-chan struct{}) error {
6363
return nil
6464
}
6565

66-
// WaitForCacheSync waits until all the caches have been synced.
66+
// WaitForCacheSync waits until all the caches have been started and synced.
6767
func (m *InformersMap) WaitForCacheSync(stop <-chan struct{}) bool {
6868
syncedFuncs := append([]cache.InformerSynced(nil), m.structured.HasSyncedFuncs()...)
6969
syncedFuncs = append(syncedFuncs, m.unstructured.HasSyncedFuncs()...)
7070

71+
if !m.structured.waitForStarted(stop) {
72+
return false
73+
}
74+
if !m.unstructured.waitForStarted(stop) {
75+
return false
76+
}
7177
return cache.WaitForCacheSync(stop, syncedFuncs...)
7278
}
7379

pkg/cache/internal/informers_map.go

+15
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func newSpecificInformersMap(config *rest.Config,
5454
codecs: serializer.NewCodecFactory(scheme),
5555
paramCodec: runtime.NewParameterCodec(scheme),
5656
resync: resync,
57+
startWait: make(chan struct{}),
5758
createListWatcher: createListWatcher,
5859
namespace: namespace,
5960
}
@@ -104,6 +105,10 @@ type specificInformersMap struct {
104105
// start is true if the informers have been started
105106
started bool
106107

108+
// startWait is a channel that is closed after the
109+
// informer has been started.
110+
startWait chan struct{}
111+
107112
// createClient knows how to create a client and a list object,
108113
// and allows for abstracting over the particulars of structured vs
109114
// unstructured objects.
@@ -131,10 +136,20 @@ func (ip *specificInformersMap) Start(stop <-chan struct{}) {
131136

132137
// Set started to true so we immediately start any informers added later.
133138
ip.started = true
139+
close(ip.startWait)
134140
}()
135141
<-stop
136142
}
137143

144+
func (ip *specificInformersMap) waitForStarted(stop <-chan struct{}) bool {
145+
select {
146+
case <-ip.startWait:
147+
return true
148+
case <-stop:
149+
return false
150+
}
151+
}
152+
138153
// HasSyncedFuncs returns all the HasSynced functions for the informers in this map.
139154
func (ip *specificInformersMap) HasSyncedFuncs() []cache.InformerSynced {
140155
ip.mu.RLock()

0 commit comments

Comments
 (0)