@@ -41,7 +41,7 @@ const globalCache = "_cluster-scope"
4141// MultiNamespacedCacheBuilder - Builder function to create a new multi-namespaced cache. 
4242// This will scope the cache to a list of namespaces. Listing for all namespaces 
4343// will list for all the namespaces that this knows about. By default this will create 
44- // a global cache for cluster scoped resource (having empty namespace) . Note that this is not intended 
44+ // a global cache for cluster scoped resource. Note that this is not intended 
4545// to be used for excluding namespaces, this is better done via a Predicate. Also note that 
4646// you may face performance issues when using this with a high number of namespaces. 
4747func  MultiNamespacedCacheBuilder (namespaces  []string ) NewCacheFunc  {
@@ -59,9 +59,6 @@ func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc {
5959			return  nil , fmt .Errorf ("error creating global cache %v" , err )
6060		}
6161
62- 		// add global cache to the cacheMap 
63- 		caches [globalCache ] =  gCache 
64- 
6562		for  _ , ns  :=  range  namespaces  {
6663			opts .Namespace  =  ns 
6764			c , err  :=  New (config , opts )
@@ -70,7 +67,7 @@ func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc {
7067			}
7168			caches [ns ] =  c 
7269		}
73- 		return  & multiNamespaceCache {namespaceToCache : caches , Scheme : opts .Scheme , RESTMapper : opts .Mapper }, nil 
70+ 		return  & multiNamespaceCache {namespaceToCache : caches , Scheme : opts .Scheme , RESTMapper : opts .Mapper ,  ClusterCache :  gCache }, nil 
7471	}
7572}
7673
@@ -82,6 +79,7 @@ type multiNamespaceCache struct {
8279	namespaceToCache  map [string ]Cache 
8380	Scheme            * runtime.Scheme 
8481	RESTMapper        meta.RESTMapper 
82+ 	ClusterCache      Cache 
8583}
8684
8785var  _  Cache  =  & multiNamespaceCache {}
@@ -96,6 +94,12 @@ func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object
9694		}
9795		informers [ns ] =  informer 
9896	}
97+ 	clusterCacheInf , err  :=  c .ClusterCache .GetInformer (ctx , obj )
98+ 	if  err  !=  nil  {
99+ 		return  nil , err 
100+ 	}
101+ 	informers [globalCache ] =  clusterCacheInf 
102+ 
99103	return  & multiNamespaceInformer {namespaceToInformer : informers }, nil 
100104}
101105
@@ -108,10 +112,24 @@ func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema
108112		}
109113		informers [ns ] =  informer 
110114	}
115+ 	clusterCacheInf , err  :=  c .ClusterCache .GetInformerForKind (ctx , gvk )
116+ 	if  err  !=  nil  {
117+ 		return  nil , err 
118+ 	}
119+ 	informers [globalCache ] =  clusterCacheInf 
111120	return  & multiNamespaceInformer {namespaceToInformer : informers }, nil 
112121}
113122
114123func  (c  * multiNamespaceCache ) Start (ctx  context.Context ) error  {
124+ 	// start global cache 
125+ 	go  func () {
126+ 		err  :=  c .ClusterCache .Start (ctx )
127+ 		if  err  !=  nil  {
128+ 			log .Error (err , "cluster scoped cache failed to start" )
129+ 		}
130+ 	}()
131+ 
132+ 	// start namespaced caches 
115133	for  ns , cache  :=  range  c .namespaceToCache  {
116134		go  func (ns  string , cache  Cache ) {
117135			err  :=  cache .Start (ctx )
@@ -120,6 +138,7 @@ func (c *multiNamespaceCache) Start(ctx context.Context) error {
120138			}
121139		}(ns , cache )
122140	}
141+ 
123142	<- ctx .Done ()
124143	return  nil 
125144}
@@ -131,6 +150,11 @@ func (c *multiNamespaceCache) WaitForCacheSync(ctx context.Context) bool {
131150			synced  =  s 
132151		}
133152	}
153+ 
154+ 	// check if cluster scoped cache has synced 
155+ 	if  ! c .ClusterCache .WaitForCacheSync (ctx ) {
156+ 		synced  =  false 
157+ 	}
134158	return  synced 
135159}
136160
@@ -140,6 +164,10 @@ func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object,
140164			return  err 
141165		}
142166	}
167+ 
168+ 	if  err  :=  c .ClusterCache .IndexField (ctx , obj , field , extractValue ); err  !=  nil  {
169+ 		return  fmt .Errorf ("error adding index on object with cluster scoped cache %v" , err )
170+ 	}
143171	return  nil 
144172}
145173
@@ -151,8 +179,7 @@ func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj
151179
152180	if  ! isNamespaced  {
153181		// Look into the global cache to fetch the object 
154- 		cache  :=  c .namespaceToCache [globalCache ]
155- 		return  cache .Get (ctx , key , obj )
182+ 		return  c .ClusterCache .Get (ctx , key , obj )
156183	}
157184
158185	cache , ok  :=  c .namespaceToCache [key .Namespace ]
@@ -174,8 +201,7 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList,
174201
175202	if  ! isNamespaced  {
176203		// Look at the global cache to get the objects with the specified GVK 
177- 		cache  :=  c .namespaceToCache [globalCache ]
178- 		return  cache .List (ctx , list , opts ... )
204+ 		return  c .ClusterCache .List (ctx , list , opts ... )
179205	}
180206
181207	if  listOpts .Namespace  !=  corev1 .NamespaceAll  {
@@ -199,10 +225,7 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList,
199225	limitSet  :=  listOpts .Limit  >  0 
200226
201227	var  resourceVersion  string 
202- 	for  ns , cache  :=  range  c .namespaceToCache  {
203- 		if  ns  ==  globalCache  {
204- 			continue 
205- 		}
228+ 	for  _ , cache  :=  range  c .namespaceToCache  {
206229		listObj  :=  list .DeepCopyObject ().(client.ObjectList )
207230		err  =  cache .List (ctx , listObj , & listOpts )
208231		if  err  !=  nil  {
0 commit comments