-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Refactor cache package. #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
3f7d90d
to
bf3559e
Compare
@seans3 This is the other half of the client PR. Once the structure looks good, we should add thorough testing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some comments inline. General approach is ok. Creating informers after start is questionable. Mutex use needs review.
pkg/cache/cache.go
Outdated
Indexer cache.Indexer | ||
// GroupVersionKind is the group-version-kind of the resource. | ||
GroupVersionKind schema.GroupVersionKind | ||
// IndexField adds an index to a field. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably needs to copy the rest of the godoc from the related fields about the what you should pass to extractValue
and the caveats, or at least have a note about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a go doc from client-go. LMK if this is the right one.
pkg/cache/cache.go
Outdated
// New initializes and returns a new Cache | ||
func New(config *rest.Config, opts Options) (Cache, error) { | ||
// Use the default Kubernetes Scheme if unset | ||
if opts.Scheme == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactor this out into an Options.ApplyDefaults
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/cache/internal/factory.go
Outdated
ip.informersByGVK[gvk] = i | ||
|
||
// Start the Informer if need by | ||
if ip.started { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm... I'd be a bit wary of this. Certain expectations break if this happens (e.g. you can't add indexers, and I'd need to double check what happens if you add new event handlers -- do you get the initial populate events)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a todo about adding tests and documentation for this.
// to be locked | ||
var sync bool | ||
i, err := func() (*MapEntry, error) { | ||
ip.mu.Lock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to cause issues, because it means that only one read operation can happen across any index at once, which is suboptimal. That's one of the reasons why the separation between creation and client lookup was useful. I think what we might want to do is
// assume the happy path first
with read-only-lock {
if i, ok := informers[gvk]; ok {
return i
}
}
// sad path, first time only
with write-lock {
// check again in case we raced
if i, ok := informers[gvk]; ok {
return i
}
// only construct if we actually need to do so
i := construct informer
informers[gvk] = i
return i
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
PTAL |
Indexer cache.Indexer | ||
// GroupVersionKind is the group-version-kind of the resource. | ||
GroupVersionKind schema.GroupVersionKind | ||
// cache is a Kubernetes Object cache populated from InformersMap. cache wraps a CacheProvider and InformersMap. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cache -> informerCache
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Indexer cache.Indexer | ||
// GroupVersionKind is the group-version-kind of the resource. | ||
GroupVersionKind schema.GroupVersionKind | ||
// cache is a Kubernetes Object cache populated from InformersMap. cache wraps a CacheProvider and InformersMap. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like informerCache only wraps an InformersMap, not a CacheProvider as stated in comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
return k.Name | ||
// Default the resync period to 10 hours if unset | ||
if opts.Resync == nil { | ||
r := 10 * time.Hour |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider pulling 10 out into a const as "defaultResyncHours"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
) | ||
|
||
// NewInformersMap returns a new InformersMap | ||
func NewInformersMap(config *rest.Config, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this file is mostly about the InformersMap, why is it called factory.go ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
return cache.WaitForCacheSync(stop, syncedFuncs...) | ||
} | ||
|
||
// Get will create a new Informer and added it to the map of InformersMap if none exists. Returns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: added -> add
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
|
||
// Do the mutex part in its own function so we can use defer without blocking pieces that don't | ||
// to be locked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: missing "need" to be locked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
var _ client.Reader = &Reader{} | ||
|
||
// Reader wraps a cache.Index to implement the client.Reader interface for a single type | ||
type Reader struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reader struct might be confused with Reader interface. You might want to consider another name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
var _ client.Reader = &informerCache{} | ||
|
||
// Get implements Reader | ||
func (ip *informerCache) Get(ctx context.Context, key client.ObjectKey, out runtime.Object) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though the informerCache implements the client.Reader interface, would this file more accurately be called informer_cache.go instead of reader.go ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nits. Not sure why tests in cache_test are commented out instead of removed.
/lgtm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests are commented out because we should uncomment them and make them pass, but they weren't running. Fixing the tests should be the next priority.
Comments addressed in #35 |
Fixup pkg/cache with comments from #29
Refactor cache package.
Fixup pkg/cache with comments from kubernetes-sigs#29
Follow up with tests for the cache and cache/internal packages.