-
Notifications
You must be signed in to change notification settings - Fork 57
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
🌱 refactor catalogmetadata types used for resolution #599
🌱 refactor catalogmetadata types used for resolution #599
Conversation
In case anyone looks at this before I get around to it, there is still a good amount of refactoring to do in the unit tests for this change. I've verified manually that the changes still result in the same functionality but I fully expect unit tests to fail as the PR currently stands |
Signed-off-by: everettraven <[email protected]>
71fe718
to
e37bb1c
Compare
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #599 +/- ##
==========================================
- Coverage 84.53% 80.98% -3.55%
==========================================
Files 20 20
Lines 931 936 +5
==========================================
- Hits 787 758 -29
- Misses 100 130 +30
- Partials 44 48 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
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 am unfortunately too far from this code to fully grok what is going on here. At the surface level the transform seems reasonable.
} | ||
|
||
func (b *Bundle) RequiredPackages() ([]PackageRequired, error) { | ||
if err := b.loadRequiredPackages(); err != 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.
I think we had these load*
to avoid unmarshaling properties multiple times. E.g. RequiredPackages
can be called 10 times during resolution process and ideally we don't want to unmarshal 10 times.
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.
Is that a realistic example though? I looked at all the references to this function and there were a total of 2 with one being in tests. The only reference to this function getting called outside of tests is:
requiredPackages, _ := bundle.RequiredPackages() |
and that function is called once for every bundle, which means every bundle is "loading" the required packages a singular time and that is it. Doesn't seem worth the additional complexity to optimize this when in the current state of the world it only gets called once for each bundle and it isn't taking advantage of that optimization.
That being said, you are more knowledgable in this space so if you have other insights that prove my assumptions wrong I'm happy to continue the discussion and make any optimizations that are worthwhile.
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.
that function is called once for every bundle
It is not always the case. Some functions can potentially be called multiple times on the single bundle. While RequiredPackages
is guarded by the visited
set here and most likely won't be called multiple times in the code as it currently stands, other functions might still get multiple calls. For example, I believe Version
will be called every time we do filtering here.
Overall we do quite a lot of filtering on allBundles
. Every time we filter on a property that needs unmarshaling - we can benefit from the optimisation.
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 personally don't see where we do enough filtering within the existing logic on properties that need unmarshaling that make me concerned about unmarshaling more than once but I'm also not that well versed on how intensive unmarshaling is.
Not a hill I'm willing to die on so I added it back in (although didn't recreate the load*
functions as it feels redundant IMO): 94fe3df
bundle.Deprecation = &declcfg.DeprecationEntry{ | ||
Reference: entry.Reference, | ||
Message: entry.Message, | ||
} |
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 I remember our conversation from January correctly, we decided to get rid of fields like InChannels
and try to keep original FBC/declcfg
stucts as much as possible. I see that InChannels
is now gone, but Deprecation
field on Bundle
and other structs was added. I think it is the same same concept.
Should we explore adding some maps in places where we need to do lookups of deprecation entries? Or something similar what you did to channels (using filters).
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 similarly recall the conversation as keeping the wrapper as simple as possible if one is necessary (at the very least we need one for that catalog name since the declcfg.*
representations don't store catalog information). I recall @joelanford mentioning adding the deprecation entry to the wrapper as well in previous conversations so I took that approach as it was one less set of information to deal with after the fact. I'm not opposed to either of the approaches though so this is more or less a "let's pick one and I'll implement it" situation.
The benefit of this approach is that there is no lookup cost after the set of packages, channels, and bundles are returned but there are definitely other solutions where the lookup cost is negligible that I'm open to exploring.
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 don't remember the context of my suggestion of putting the deprecation entry in the wrapper, but I think I'd suggest separating it out and keeping the structure similar to the FBC structure.
channels := filter.Filter[catalogmetadata.Channel](allChannels, filter.And[catalogmetadata.Channel]( | ||
func(entity *catalogmetadata.Channel) bool { | ||
return entity.Package == clusterExtension.Spec.PackageName | ||
}, | ||
func(entity *catalogmetadata.Channel) bool { | ||
if clusterExtension.Spec.Channel != "" { | ||
return entity.Name == clusterExtension.Spec.Channel | ||
} | ||
return true | ||
}, | ||
)) |
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.
Wondering if we can build a map of package -> channel once and re-used it multiple times to avoid iterating trough all the channel date for each call to this function.
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.
We certainly could, but I wasn't sure if that optimization is worth the overhead / additional complexity within the client logic. I'm definitely open to discussing optimization in this PR, but also want to make sure we aren't prematurely trying to optimize and dig ourselves into a different hole of complexity. Especially since there has been mention of potentially not even needing to have a sat solver that could result in needing to refactor a large chunk of this logic again.
Signed-off-by: everettraven <[email protected]>
Signed-off-by: everettraven <[email protected]>
PR needs rebase. 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. |
Description
Refactors the types in the
internal/catalogmetadata
package to reduce the complexity of requiring all the OLM-isms to be conveyed through the singleBundle
type. Updates all resolution logic and unit tests as needed.resolves Deppy: remove assumption about entities being members of channels #176 (?)
Any other issues folks think this resolves?
Reviewer Checklist