Skip to content
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

🌱 Add a design document to filter cache by selectors #1419

Merged

Conversation

qinqon
Copy link
Contributor

@qinqon qinqon commented Mar 9, 2021

The controller-runtime is caching all the resource instance even if not
all of them end up being reconciled, this design document describe a
proposal to that problem by use selectors at the ListWatch informers
mechanism.

This is related to #1404

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Mar 9, 2021
@k8s-ci-robot
Copy link
Contributor

Hi @qinqon. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Mar 9, 2021
@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Mar 9, 2021
@alvaroaleman
Copy link
Member

@qinqon thanks for putting this up! Could you join the kubebuilder and controller-runtime biweekly meeting this Thursday 18 CET and show it briefly?

@qinqon
Copy link
Contributor Author

qinqon commented Mar 9, 2021

@alvaroaleman sure, I will be there.

@qinqon
Copy link
Contributor Author

qinqon commented Mar 11, 2021

@alvaroaleman do I have to add a bullet to the agenda or just rise a hand on the meeting ?

@alvaroaleman
Copy link
Member

@qinqon a bullet would be great

@qinqon
Copy link
Contributor Author

qinqon commented Mar 12, 2021

/cc @alvaroaleman @vincepri

Let me know if I have to pin someone else here, so we can discuss it.

@qinqon qinqon force-pushed the add-cache-filter-field-option branch from 69c3cbf to e2bc322 Compare March 16, 2021 09:34
@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 16, 2021
@qinqon
Copy link
Contributor Author

qinqon commented Mar 16, 2021

force-push: Removed pkg/cache changes from this PR, converted map value to fields.Selector and added warning to proposal.

@qinqon qinqon force-pushed the add-cache-filter-field-option branch from e2bc322 to 95dbc43 Compare March 16, 2021 11:31
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Mar 16, 2021
@qinqon
Copy link
Contributor Author

qinqon commented Mar 16, 2021

force-push: Added an additional proposal to pass the selector using the builder instead of manager.Options as implemented in #1425

@qinqon qinqon force-pushed the add-cache-filter-field-option branch from 95dbc43 to abadf65 Compare March 17, 2021 09:15
@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 17, 2021
@qinqon
Copy link
Contributor Author

qinqon commented Mar 17, 2021

force-push: Removed proposal 2 and adapterd former proposal to use NewCache using a builder function that will return a constructor.

@qinqon
Copy link
Contributor Author

qinqon commented Mar 17, 2021

Does it make sense to include labels in this proposal ?, the interfaces to use labels are almost identicall to fields and we will be able to close the issue.

UPDATE: Created a PoC adding labels too #1435

@k8s-ci-robot k8s-ci-robot added lgtm "Looks good to me", indicates that a PR is ready to be merged. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Apr 5, 2021
@alvaroaleman
Copy link
Member

/hold
for others

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 5, 2021
Comment on lines 43 to 44
// SelectorsByObject associate a GroupResource to a field/label selector
type SelectorsByGVK map[schema.GVK]Selector
Copy link
Contributor

@estroz estroz Apr 5, 2021

Choose a reason for hiding this comment

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

Nit

Suggested change
// SelectorsByObject associate a GroupResource to a field/label selector
type SelectorsByGVK map[schema.GVK]Selector
// SelectorsByGVK associate a GroupVersionKind to a field/label selector
type SelectorsByGVK map[schema.GroupVersionKind]Selector

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

...

// SelectorsByObject associate a client.Object to a field/label selector
type SelectorsByObject map[client.Object]Selector
Copy link
Contributor

@estroz estroz Apr 5, 2021

Choose a reason for hiding this comment

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

This should be restricted to runtime.Object so users don't get the idea that you can filter by object name/namespace via SetName() and SetNamespace().

Suggested change
type SelectorsByObject map[client.Object]Selector
type SelectorsByObject map[runtime.Object]Selector

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
Member

Choose a reason for hiding this comment

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

@estroz why? It is a map, the values can not access the keys. Making this runtime.Object means we have to deal with stuff like ppl putting List types in there

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@alvaroaleman don't we have the same problem with client.Object since it's embedding runtime.Object ?

Copy link
Contributor

Choose a reason for hiding this comment

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

@alvaroaleman it may be confusing to users to have all these object fields exposed by the metav1.Object, since they may assume the key can actually apply its own selector values, ex. by SetName(). Instead it would be better to constrain the contract to just GroupVersionKind().

There can be some internal validation step to make sure the object is not a list type.

Copy link
Member

Choose a reason for hiding this comment

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

Using GVK is inconvenient. Using the smaller interface (runtime.Object) doesn't prevent ppl from putting in objects that fulfill a lager interface (client.Object). It does however keep them from putting something like List types in there and makes the compiler verify that rather than getting a runtime error. Also, I think the idea that ppl might think the map key has any further relevance for filtering when the value is a Selector struct seems a bit far fetched to me.

We also have plenty of prior art where we use client.Object to only derive the type, e.G. in source.Kind or the clients delete method.

Copy link
Contributor

Choose a reason for hiding this comment

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

You could similarly argue that someone would not try to map a selector to a list type because that's not the type they add to For(), Owns(), or Watches().

However since there is prior art I am fine with client.Object. There can always be another selector map type added later for runtime.Object without breakage if we see bugs filed because of confusion. It's not worth worrying about too much now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Going back to client.Object as proposed originally.

}

// FillInListOpts fill in ListOptions LabelSelector and FieldSelector if needed
func (s Selector) FillInListOpts(listOpts *metav1.ListOptions) {
Copy link
Contributor

Choose a reason for hiding this comment

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

How about

Suggested change
func (s Selector) FillInListOpts(listOpts *metav1.ListOptions) {
func (s Selector) ApplyToList(listOpts *client.ListOptions) {

so it implements client.ListOption

Copy link
Contributor Author

@qinqon qinqon Apr 6, 2021

Choose a reason for hiding this comment

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

Since we are receiving metav1.ListOptions at ListWatch functions I will keep the type so we don't have to do convertions, but changing the name to ApplyToList feels good.

Mapper meta.RESTMapper
Resync *time.Duration
Namespace string
SelectorsByObject SelectorsByObject
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice to generalize this to something like

Suggested change
SelectorsByObject SelectorsByObject
Selectors SelectorSet

Where SelectorSet is any set of selectors that implements

type SelectorSet interface {
	client.ListOption
	Select()
}

where Select() is just an identifier method so users don't pass in other client.ListOptions.

Copy link
Contributor Author

@qinqon qinqon Apr 6, 2021

Choose a reason for hiding this comment

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

We apply options per GVK so it does not make sense to implement ListOption at the map level.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, get rid of client.ListOption from that interface. Regardless, I may want to construct a GVK myself instead of using a typed object or Unstructured, so why not also expose SelectorsByGVK?

Copy link
Contributor Author

@qinqon qinqon Apr 8, 2021

Choose a reason for hiding this comment

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

As we have previously stated we are going to expose the map key as client.Object, internally will be GVK, in fact at the implementation PR I will remove SelectorsByObject from internal and use it only as a type to pass to the cache Options, at Options parsing it will be converted to the SelectorsByGVK.

@qinqon qinqon force-pushed the add-cache-filter-field-option branch from e9f3b9d to 3c3313f Compare April 6, 2021 08:14
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Apr 6, 2021
@qinqon qinqon requested a review from estroz April 6, 2021 09:05
The controller-runtime is caching all the resource instance even if not
all of them end up being reconciled, this design document describe a
proposal to that problem by use selectors at the ListWatch informers
mechanism.

Signed-off-by: Quique Llorente <ellorent@redhat.com>
@qinqon qinqon force-pushed the add-cache-filter-field-option branch from 3c3313f to 141ddd6 Compare April 8, 2021 06:19
@qinqon
Copy link
Contributor Author

qinqon commented Apr 8, 2021

Before we merge this, can you confirm that we don't want to have something like client.ListOptions as the map value to allow users to filter with all the possible options not only selectors.

@alvaroaleman
Copy link
Member

Before we merge this, can you confirm that we don't want to have something like client.ListOptions as the map value to allow users to filter with all the possible options not only selectors.

What other options exist that we could filter by? Only the namespace or not?

@qinqon
Copy link
Contributor Author

qinqon commented Apr 8, 2021

Before we merge this, can you confirm that we don't want to have something like client.ListOptions as the map value to allow users to filter with all the possible options not only selectors.

What other options exist that we could filter by? Only the namespace or not?

The other options are more dangerous than useful, so yes.

@alvaroaleman
Copy link
Member

The other options are more dangerous than useful, so yes.

Yeah, the namespace is a bit redundant as its also a global option. Generally, we can easily extend the Selector in the future in a backwards-compatible way if we see a reason, so I am not too concerned about missing something there.

@qinqon
Copy link
Contributor Author

qinqon commented Apr 12, 2021

@estroz are you ok with the changes ?

Copy link
Contributor

@estroz estroz left a comment

Choose a reason for hiding this comment

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

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Apr 12, 2021
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: alvaroaleman, estroz, qinqon

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@alvaroaleman
Copy link
Member

/hold cancel
Lets get this done!

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 12, 2021
@alvaroaleman
Copy link
Member

/retest

@qinqon
Copy link
Contributor Author

qinqon commented Apr 13, 2021

/retest

I think we can override the job clearly is not related

@qinqon
Copy link
Contributor Author

qinqon commented Apr 13, 2021

/test pull-controller-runtime-test-master

@alvaroaleman
Copy link
Member

/retest

@k8s-ci-robot k8s-ci-robot merged commit 2d6828d into kubernetes-sigs:master Apr 13, 2021
@k8s-ci-robot k8s-ci-robot added this to the v0.9.x milestone Apr 13, 2021
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. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants