-
Notifications
You must be signed in to change notification settings - Fork 40.1k
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
Create TransformingInformer #104300
Create TransformingInformer #104300
Conversation
/assign @liggitt |
return clientState, newInformer(lw, objType, resyncPeriod, h, clientState, nil) | ||
} | ||
|
||
// TransformFunc allows for transforming an object before it will be processed |
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.
@liggitt - obviously tests are missing in this PR, but before I go ahead and add them I would appreciate some early feedback on this change.
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.
@deads2k - would you mind providing some early feedback?
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.
I'm ok with the idea, but I'd like to be sure that the layers above this one make it difficult to accidentally confuse your listers with different transformations.
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.
make it difficult to accidentally confuse your listers with different transformations.
Can you clarify? Is the comment about naming mostly? If so, I'm happy to change if you have better suggestions.
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.
make it difficult to accidentally confuse your listers with different transformations.
Can you clarify? Is the comment about naming mostly? If so, I'm happy to change if you have better suggestions.
Today we generate Informers and Listers for every type. I'm somewhat concerned that people will make a TransformingPodLister, but if the type is still PodLister, it could get improperly passed around. I think we can expect people making use of a transformed PodLister to accept a different type. Does that seem reasonable?
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.
Got it [I though that this comment is related to Transform itself, whereas it's more related to the returned values of "NewTransformingInformer"], i.e. the fact that it returns (Store, Controller).
The Controller
itself doesn't seem controversial to me.
The potential problem is Store
, as (IIUC what you're saying) it may lead to people thinking it contains different things (i.e. whole objects) than it really contains.
[The Lister itself isn't (at least in the shape of this PR a problem, because it requires indexer which I don't create here, but the change would be too simple to add to ignore it.]
So IIUC, what you're saying is that instead of returning Store
, we should consider returning TransformingStore
(or sth like that). Do I understand correctly?
If so, this effectively would be the same interface, so it would be possible once to another, so I'm not sure it would really bring value. WDYT?
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 so, this effectively would be the same interface, so it would be possible once to another, so I'm not sure it would really bring value. WDYT?
Duck typing never fails to disappoint. I think you're right.
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: wojtek-t 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 |
/triage accepted |
@@ -393,24 +425,33 @@ func newInformer( | |||
Process: func(obj interface{}) error { | |||
// from oldest to newest | |||
for _, d := range obj.(Deltas) { | |||
obj := d.Object | |||
if transformer != 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.
Have I correctly skimmed the code below and it computes the keys for any indexes after the transform, so the data to compute is always present in the returned instances?
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.
and it computes the keys for any indexes after the transform,
Yes.
so the data to compute is always present in the returned instances?
I guess it depends on the indexes that are passed. But in the correct usage the index should only use data from transformed objects.
I don't object in principle, but are we sure that we'd rather invest this way as opposed to making it easy to use the metadata only list/watch? I remember garbage collection tried, but I don't recall how successful it was. |
Thanks @deads2k . Given the above, I will go ahead and try to add tests in the upcoming weeks and will ask you for more detailed review then. |
1e1e3ea
to
c629322
Compare
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.
I have added a test - this is now ready for a more formal review.
@deads2k - PTAL when you will have a chance.
@@ -393,24 +425,33 @@ func newInformer( | |||
Process: func(obj interface{}) error { | |||
// from oldest to newest | |||
for _, d := range obj.(Deltas) { | |||
obj := d.Object | |||
if transformer != 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.
and it computes the keys for any indexes after the transform,
Yes.
so the data to compute is always present in the returned instances?
I guess it depends on the indexes that are passed. But in the correct usage the index should only use data from transformed objects.
c629322
to
47551e8
Compare
47551e8
to
022469f
Compare
// The given transform function will be called on all objects before they will | ||
// put put into the Store and corresponding Add/Modify/Delete handlers will | ||
// be invokved for them. | ||
func NewTransformingInformer( |
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.
Will there be an indexer option? Why or why not?
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.
I didn't initially add indexer option as neither of the examples of this pattern I saw was using indexes.
But in the end - adding it is just a boilerplate, so we should probably do that in one shot.
I added that in a second commit.
TransformingInfomer is like a regular Informer, but allows for applying custom transform functions on the objects received via list/watch API calls.
022469f
to
56ffb4e
Compare
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.
@deads2k - PTAL
// The given transform function will be called on all objects before they will | ||
// put put into the Store and corresponding Add/Modify/Delete handlers will | ||
// be invokved for them. | ||
func NewTransformingInformer( |
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.
I didn't initially add indexer option as neither of the examples of this pattern I saw was using indexes.
But in the end - adding it is just a boilerplate, so we should probably do that in one shot.
I added that in a second commit.
/lgtm |
/retest |
2 similar comments
/retest |
/retest |
Given that this is a feature, shouldn't it have a release note? |
I don't agree. This isn't a feature per-se. This isn't anything that impact users and/or cluster admins. |
TransformingInfomer is like a regular Informer, but allows for applying custom transform functions on the objects received via list/watch API calls.
This pattern was first used in CoreDNS couple years ago:
https://github.com/coredns/coredns/blob/9d5b8cd13d541cc3d2b7598ab255643d6298ba9d/plugin/kubernetes/object/informer.go#L30
Over time, with increasing amount of controllers and developers being more conscious about memory usage, I'm seeing more and more places where this could be potentially used. So it makes sense to actually make it supported by the client-go libraries natively.
/sig api-machinery
/kind feature
/priority important-longterm