diff --git a/pkg/cache/multi_namespace_cache.go b/pkg/cache/multi_namespace_cache.go index ed37b6dd7f..a5a78fae17 100644 --- a/pkg/cache/multi_namespace_cache.go +++ b/pkg/cache/multi_namespace_cache.go @@ -41,7 +41,7 @@ const globalCache = "_cluster-scope" // MultiNamespacedCacheBuilder - Builder function to create a new multi-namespaced cache. // This will scope the cache to a list of namespaces. Listing for all namespaces // will list for all the namespaces that this knows about. By default this will create -// a global cache for cluster scoped resource (having empty namespace). Note that this is not intended +// a global cache for cluster scoped resource. Note that this is not intended // to be used for excluding namespaces, this is better done via a Predicate. Also note that // you may face performance issues when using this with a high number of namespaces. func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc { @@ -59,9 +59,6 @@ func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc { return nil, fmt.Errorf("error creating global cache %v", err) } - // add global cache to the cacheMap - caches[globalCache] = gCache - for _, ns := range namespaces { opts.Namespace = ns c, err := New(config, opts) @@ -70,7 +67,7 @@ func MultiNamespacedCacheBuilder(namespaces []string) NewCacheFunc { } caches[ns] = c } - return &multiNamespaceCache{namespaceToCache: caches, Scheme: opts.Scheme, RESTMapper: opts.Mapper}, nil + return &multiNamespaceCache{namespaceToCache: caches, Scheme: opts.Scheme, RESTMapper: opts.Mapper, clusterCache: gCache}, nil } } @@ -82,6 +79,7 @@ type multiNamespaceCache struct { namespaceToCache map[string]Cache Scheme *runtime.Scheme RESTMapper meta.RESTMapper + clusterCache Cache } var _ Cache = &multiNamespaceCache{} @@ -96,6 +94,12 @@ func (c *multiNamespaceCache) GetInformer(ctx context.Context, obj client.Object } informers[ns] = informer } + clusterCacheInf, err := c.clusterCache.GetInformer(ctx, obj) + if err != nil { + return nil, err + } + informers[globalCache] = clusterCacheInf + return &multiNamespaceInformer{namespaceToInformer: informers}, nil } @@ -108,10 +112,24 @@ func (c *multiNamespaceCache) GetInformerForKind(ctx context.Context, gvk schema } informers[ns] = informer } + clusterCacheInf, err := c.clusterCache.GetInformerForKind(ctx, gvk) + if err != nil { + return nil, err + } + informers[globalCache] = clusterCacheInf return &multiNamespaceInformer{namespaceToInformer: informers}, nil } func (c *multiNamespaceCache) Start(ctx context.Context) error { + // start global cache + go func() { + err := c.clusterCache.Start(ctx) + if err != nil { + log.Error(err, "cluster scoped cache failed to start") + } + }() + + // start namespaced caches for ns, cache := range c.namespaceToCache { go func(ns string, cache Cache) { err := cache.Start(ctx) @@ -120,6 +138,7 @@ func (c *multiNamespaceCache) Start(ctx context.Context) error { } }(ns, cache) } + <-ctx.Done() return nil } @@ -131,6 +150,11 @@ func (c *multiNamespaceCache) WaitForCacheSync(ctx context.Context) bool { synced = s } } + + // check if cluster scoped cache has synced + if !c.clusterCache.WaitForCacheSync(ctx) { + synced = false + } return synced } @@ -140,6 +164,10 @@ func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object, return err } } + + if err := c.clusterCache.IndexField(ctx, obj, field, extractValue); err != nil { + return fmt.Errorf("error adding index on object with cluster scoped cache %v", err) + } return nil } @@ -151,8 +179,7 @@ func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj if !isNamespaced { // Look into the global cache to fetch the object - cache := c.namespaceToCache[globalCache] - return cache.Get(ctx, key, obj) + return c.clusterCache.Get(ctx, key, obj) } cache, ok := c.namespaceToCache[key.Namespace] @@ -174,8 +201,7 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList, if !isNamespaced { // Look at the global cache to get the objects with the specified GVK - cache := c.namespaceToCache[globalCache] - return cache.List(ctx, list, opts...) + return c.clusterCache.List(ctx, list, opts...) } if listOpts.Namespace != corev1.NamespaceAll { @@ -199,10 +225,7 @@ func (c *multiNamespaceCache) List(ctx context.Context, list client.ObjectList, limitSet := listOpts.Limit > 0 var resourceVersion string - for ns, cache := range c.namespaceToCache { - if ns == globalCache { - continue - } + for _, cache := range c.namespaceToCache { listObj := list.DeepCopyObject().(client.ObjectList) err = cache.List(ctx, listObj, &listOpts) if err != nil {