Skip to content

Commit 934f564

Browse files
author
Shawn Hurley
committed
helper structure to hide which map to use.
1 parent f55d28c commit 934f564

File tree

1 file changed

+32
-41
lines changed

1 file changed

+32
-41
lines changed

pkg/cache/internal/informers_map.go

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ type InformersMap struct {
7777

7878
// unstructuredInformerByGVK is a cache of informers for unstructured types
7979
// keyed by groupVersionKind
80+
// This is separate from informerByGVK because you don't want to
81+
// request a structured object but get an unstructured informer and
82+
// vice versa
8083
unstructuredInformerByGVK map[schema.GroupVersionKind]*MapEntry
8184

8285
// codecs is used to create a new REST client
@@ -100,6 +103,12 @@ type InformersMap struct {
100103
started bool
101104
}
102105

106+
type mutexMap struct {
107+
informerByGVK map[schema.GroupVersionKind]*MapEntry
108+
// mu guards access to the unstructured map
109+
mu *sync.RWMutex
110+
}
111+
103112
// Start calls Run on each of the informers and sets started to true. Blocks on the stop channel.
104113
func (ip *InformersMap) Start(stop <-chan struct{}) error {
105114
func() {
@@ -140,28 +149,31 @@ func (ip *InformersMap) WaitForCacheSync(stop <-chan struct{}) bool {
140149
return cache.WaitForCacheSync(stop, syncedFuncs...)
141150
}
142151

143-
func (ip *InformersMap) getMapEntry(gvk schema.GroupVersionKind, isUnstructured bool) (*MapEntry, bool) {
144-
if isUnstructured {
145-
ip.unstructuredMu.RLock()
146-
defer ip.unstructuredMu.RUnlock()
147-
i, ok := ip.unstructuredInformerByGVK[gvk]
148-
return i, ok
149-
}
150-
ip.mu.RLock()
151-
defer ip.mu.RUnlock()
152-
i, ok := ip.informersByGVK[gvk]
153-
return i, ok
154-
155-
}
156-
157152
// Get will create a new Informer and add it to the map of InformersMap if none exists. Returns
158153
// the Informer from the map.
159154
func (ip *InformersMap) Get(gvk schema.GroupVersionKind, obj runtime.Object) (*MapEntry, error) {
160155
_, isUnstructured := obj.(*unstructured.Unstructured)
161156
_, isUnstructuredList := obj.(*unstructured.UnstructuredList)
162-
isUnstructured = isUnstructured || isUnstructuredList
157+
mm := mutexMap{
158+
informerByGVK: ip.informersByGVK,
159+
mu: &ip.mu,
160+
}
161+
// If unstructured use the unstructured mutext and map.
162+
if isUnstructured || isUnstructuredList {
163+
mm = mutexMap{
164+
informerByGVK: ip.unstructuredInformerByGVK,
165+
mu: &ip.unstructuredMu,
166+
}
167+
}
168+
163169
// Return the informer if it is found
164-
i, ok := ip.getMapEntry(gvk, isUnstructured)
170+
i, ok := func() (*MapEntry, bool) {
171+
mm.mu.RLock()
172+
defer mm.mu.RUnlock()
173+
i, ok := mm.informerByGVK[gvk]
174+
return i, ok
175+
176+
}()
165177
if ok {
166178
return i, nil
167179
}
@@ -170,20 +182,9 @@ func (ip *InformersMap) Get(gvk schema.GroupVersionKind, obj runtime.Object) (*M
170182
// need to be locked
171183
var sync bool
172184
i, err := func() (*MapEntry, error) {
173-
var ok bool
174-
var i *MapEntry
175-
// Check the caches to see if we already have an Informer. If we do, return the Informer.
176-
// This is for the case where 2 routines tried to get the informer when it wasn't in the map
177-
// so neither returned early, but the first one created it.
178-
if isUnstructured {
179-
ip.unstructuredMu.Lock()
180-
defer ip.unstructuredMu.Unlock()
181-
i, ok = ip.unstructuredInformerByGVK[gvk]
182-
} else {
183-
ip.mu.Lock()
184-
defer ip.mu.Unlock()
185-
i, ok = ip.informersByGVK[gvk]
186-
}
185+
mm.mu.Lock()
186+
defer mm.mu.Unlock()
187+
i, ok = mm.informerByGVK[gvk]
187188
if ok {
188189
return i, nil
189190
}
@@ -201,7 +202,7 @@ func (ip *InformersMap) Get(gvk schema.GroupVersionKind, obj runtime.Object) (*M
201202
Informer: ni,
202203
Reader: CacheReader{indexer: ni.GetIndexer(), groupVersionKind: gvk},
203204
}
204-
ip.setMap(i, gvk, isUnstructured)
205+
mm.informerByGVK[gvk] = i
205206

206207
// Start the Informer if need by
207208
// TODO(seans): write thorough tests and document what happens here - can you add indexers?
@@ -226,16 +227,6 @@ func (ip *InformersMap) Get(gvk schema.GroupVersionKind, obj runtime.Object) (*M
226227
return i, err
227228
}
228229

229-
// setMap - helper function to decide which map to add to.
230-
func (ip *InformersMap) setMap(i *MapEntry, gvk schema.GroupVersionKind, isUnstructured bool) {
231-
if isUnstructured {
232-
ip.unstructuredInformerByGVK[gvk] = i
233-
} else {
234-
235-
ip.informersByGVK[gvk] = i
236-
}
237-
}
238-
239230
// newListWatch returns a new ListWatch object that can be used to create a SharedIndexInformer.
240231
func (ip *InformersMap) newListWatch(gvk schema.GroupVersionKind, isUnstructured bool) (*cache.ListWatch, error) {
241232
// Kubernetes APIs work against Resources, not GroupVersionKinds. Map the

0 commit comments

Comments
 (0)