Skip to content

Commit 8cf25e7

Browse files
committed
Address comments
1 parent 0b7f6ac commit 8cf25e7

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

pkg/cache/cache.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package cache
1919
import (
2020
"time"
2121

22+
"fmt"
23+
2224
"github.com/kubernetes-sigs/controller-runtime/pkg/cache/internal"
2325
"github.com/kubernetes-sigs/controller-runtime/pkg/client"
2426
"github.com/kubernetes-sigs/controller-runtime/pkg/client/apiutil"
@@ -60,7 +62,11 @@ type Informers interface {
6062
// WaitForCacheSync waits for all the caches to sync. Returns false if it could not sync a cache.
6163
WaitForCacheSync(stop <-chan struct{}) bool
6264

63-
// IndexField adds an index to a field.
65+
// IndexField adds an index with the given field name on the given object type
66+
// by using the given function to extract the value for that field. If you want
67+
// compatibility with the Kubernetes API server, only return one key, and only use
68+
// fields that the API server supports. Otherwise, you can return multiple keys,
69+
// and "equality" in the field selector means that at least one key matches the value.
6470
IndexField(obj runtime.Object, field string, extractValue client.IndexerFunc) error
6571
}
6672

@@ -85,8 +91,7 @@ type informerCache struct {
8591
*internal.InformersMap
8692
}
8793

88-
// New initializes and returns a new Cache
89-
func New(config *rest.Config, opts Options) (Cache, error) {
94+
func Default(config *rest.Config, opts Options) (Options, error) {
9095
// Use the default Kubernetes Scheme if unset
9196
if opts.Scheme == nil {
9297
opts.Scheme = scheme.Scheme
@@ -98,7 +103,7 @@ func New(config *rest.Config, opts Options) (Cache, error) {
98103
opts.Mapper, err = apiutil.NewDiscoveryRESTMapper(config)
99104
if err != nil {
100105
log.WithName("setup").Error(err, "Failed to get API Group-Resources")
101-
return nil, err
106+
return opts, fmt.Errorf("could not create RESTMapper from config")
102107
}
103108
}
104109

@@ -107,7 +112,15 @@ func New(config *rest.Config, opts Options) (Cache, error) {
107112
r := 10 * time.Hour
108113
opts.Resync = &r
109114
}
115+
return opts, nil
116+
}
110117

118+
// New initializes and returns a new Cache
119+
func New(config *rest.Config, opts Options) (Cache, error) {
120+
opts, err := Default(config, opts)
121+
if err != nil {
122+
return nil, err
123+
}
111124
im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync)
112125
return &informerCache{InformersMap: im}, nil
113126
}

pkg/cache/internal/factory.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ type InformersMap struct {
8686
resync time.Duration
8787

8888
// mu guards access to the map
89-
mu sync.Mutex
89+
mu sync.RWMutex
9090

9191
// start is true if the informers have been started
9292
started bool
@@ -125,6 +125,17 @@ func (ip *InformersMap) WaitForCacheSync(stop <-chan struct{}) bool {
125125
// Get will create a new Informer and added it to the map of InformersMap if none exists. Returns
126126
// the Informer from the map.
127127
func (ip *InformersMap) Get(gvk schema.GroupVersionKind, obj runtime.Object) (*MapEntry, error) {
128+
// Return the informer if it is found
129+
i, ok := func() (*MapEntry, bool) {
130+
ip.mu.RLock()
131+
defer ip.mu.RUnlock()
132+
i, ok := ip.informersByGVK[gvk]
133+
return i, ok
134+
}()
135+
if ok {
136+
return i, nil
137+
}
138+
128139
// Do the mutex part in its own function so we can use defer without blocking pieces that don't
129140
// to be locked
130141
var sync bool
@@ -133,6 +144,8 @@ func (ip *InformersMap) Get(gvk schema.GroupVersionKind, obj runtime.Object) (*M
133144
defer ip.mu.Unlock()
134145

135146
// Check the cache to see if we already have an Informer. If we do, return the Informer.
147+
// This is for the case where 2 routines tried to get the informer when it wasn't in the map
148+
// so neither returned early, but the first one created it.
136149
var ok bool
137150
i, ok := ip.informersByGVK[gvk]
138151
if ok {
@@ -152,6 +165,8 @@ func (ip *InformersMap) Get(gvk schema.GroupVersionKind, obj runtime.Object) (*M
152165
ip.informersByGVK[gvk] = i
153166

154167
// Start the Informer if need by
168+
// TODO(seans): write thorough tests and document what happens here - can you add indexers?
169+
// can you add eventhandlers?
155170
if ip.started {
156171
sync = true
157172
go i.Informer.Run(ip.stop)

0 commit comments

Comments
 (0)