Skip to content

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

Merged
merged 4 commits into from
Jun 14, 2018
Merged

Conversation

pwittrock
Copy link
Contributor

@pwittrock pwittrock commented Jun 13, 2018

Follow up with tests for the cache and cache/internal packages.

@k8s-ci-robot k8s-ci-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Jun 13, 2018
@pwittrock pwittrock requested a review from seans3 June 13, 2018 04:48
@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jun 13, 2018
@pwittrock pwittrock force-pushed the cache branch 2 times, most recently from 3f7d90d to bf3559e Compare June 13, 2018 14:38
@pwittrock
Copy link
Contributor Author

@seans3 This is the other half of the client PR. Once the structure looks good, we should add thorough testing.

Copy link
Contributor

@DirectXMan12 DirectXMan12 left a 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.

Indexer cache.Indexer
// GroupVersionKind is the group-version-kind of the resource.
GroupVersionKind schema.GroupVersionKind
// IndexField adds an index to a field.
Copy link
Contributor

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.

Copy link
Contributor Author

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.

// 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 {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

ip.informersByGVK[gvk] = i

// Start the Informer if need by
if ip.started {
Copy link
Contributor

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)

Copy link
Contributor Author

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()
Copy link
Contributor

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
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@pwittrock
Copy link
Contributor Author

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cache -> informerCache

Copy link
Contributor Author

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.
Copy link
Contributor

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.

Copy link
Contributor Author

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
Copy link
Contributor

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"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@droot droot left a 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,
Copy link
Contributor

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 ?

Copy link
Contributor Author

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
Copy link
Contributor

@seans3 seans3 Jun 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: added -> add

Copy link
Contributor Author

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
Copy link
Contributor

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.

Copy link
Contributor Author

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 {
Copy link
Contributor

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.

Copy link
Contributor Author

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 {
Copy link
Contributor

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 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@seans3 seans3 left a 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.

@seans3
Copy link
Contributor

seans3 commented Jun 13, 2018

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 13, 2018
@pwittrock pwittrock added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 14, 2018
@k8s-ci-robot k8s-ci-robot merged commit bdb5f7c into kubernetes-sigs:master Jun 14, 2018
Copy link
Contributor Author

@pwittrock pwittrock left a 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.

pwittrock added a commit to pwittrock/controller-runtime that referenced this pull request Jun 14, 2018
@pwittrock
Copy link
Contributor Author

Comments addressed in #35

k8s-ci-robot added a commit that referenced this pull request Jun 14, 2018
Fixup pkg/cache with comments from #29
justinsb pushed a commit to justinsb/controller-runtime that referenced this pull request Dec 7, 2018
justinsb pushed a commit to justinsb/controller-runtime that referenced this pull request Dec 7, 2018
justinsb pushed a commit to justinsb/controller-runtime that referenced this pull request Dec 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants