-
Notifications
You must be signed in to change notification settings - Fork 422
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
🐛 Change the type of markers.Collector.byPackage
's key from string
to *loader.Package
#792
Conversation
Welcome @ntoofu! |
Hi @ntoofu. 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 Once the patch is verified, the new status will be reflected by the 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. |
Markers might be lost in generated CRD when the package containing markers is referenced by several packages and CRD is generated by those packages. For more details, see kubernetes-sigs#783.
Markers are saved per `*ast.TypeSpec`, which is specific to `Package` object. `*ast.TypeSpec` in another `Package` object is different even when the `Package.ID` is the same, and so collected markers cannot be reused for another `Package` object. Therefore, `Package` itself is used as a key for cache of markers insetead of `Package.ID`. For more details about the bug, see kubernetes-sigs#783.
markers.Collector.byPackage
's key from string
to *loader.Package
/ok-to-test |
Thx for the extensive explanation here: #783 (comment) /lgtm |
@@ -31,7 +31,7 @@ import ( | |||
type Collector struct { | |||
*Registry | |||
|
|||
byPackage map[string]map[ast.Node]MarkerValues | |||
byPackage map[*loader.Package]map[ast.Node]MarkerValues |
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 stores the package based on the pointer's value, is there any other way that doesn't rely on where the memory is allocated?
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.
Thank you for your reviewing!
There is possibly another way, but it may be complicated.
byPackage
has two keys, package ID (string
) and node (ast.Node
). Package ID is not a pointer's value, while node is an interface and can be a struct containing pointers. That inconsistency is the root cause of this issue.
In the problematic situation, exactly the same package is loaded several times. Among each load, the package ID is the same but nodes are different objects. Parsing markers is skipped when the same package ID is already processed. Therefore, byPackage
's node keys are created only at the first time. As a result, accessing byPackage
using node as a key fails from the second load of the package.
To avoid to use pointer's value as byPackage
's key, I think we have to do one of the following.
- Stop using
ast.Node
as a key (but I have no idea about the alternative) - Do not skip parsing markers even if a package with the same ID is already parsed
- Stop loading the same package multiple times (but I have no idea why the multiple load occurs)
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.
Yup agree. The problem is definitely that we cache the markers (with pointers) by package ID and then try to use them for another package (which has different ast nodes).
(Basically byPackage is map[string]map[ast.Node][]markerComment, where ast.Node is an interface and can be e.g. *ast.File, *ast.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.
I think it should be not worse to use *loader.Package as a map key then it already is to use the ast.Node interface (aka e.g. *ast.File) as a map key one layer deeper)
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's fair, it's a bit triggering though in review 😄
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.
Yeah 100% :)
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ntoofu, vincepri 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 |
/cherry-pick release-0.11 |
@sbueringer: new pull request created: #833 In response to this:
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. |
Oh don't need the fix in release-0.11 (although no objection to merge there). Just missed that we have a v0.12 release because we don't have a release branch for v0.12 yet |
I created a release-0.12 branch based on v0.12.0 /cherry-pick release-0.12 |
@sbueringer: new pull request created: #834 In response to this:
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. |
Fix #783.
As I described in #783 (comment) , this issue is caused by using
Package.ID
as a key for cache of markers. This PR adds a testcase to reproduce the issue and fixes it by usingPackage
itself instead.