-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
[component] Make InstanceID immutable #10495
Conversation
bbfba13
to
26d02fb
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #10495 +/- ##
==========================================
- Coverage 91.68% 91.67% -0.02%
==========================================
Files 404 405 +1
Lines 18947 18971 +24
==========================================
+ Hits 17371 17391 +20
- Misses 1217 1221 +4
Partials 359 359 ☔ View full report in Codecov by Sentry. |
26d02fb
to
e9004ae
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.
This LGTM. I am happy to merge this if we have a link to an issue on grafana/alloy and grafana/agent about this change
I'll get on those issues and bring this out of draft and rebase. |
e9004ae
to
18dccc3
Compare
Issues have been opened in the respective grafana repos: |
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.
Just a couple of drive-by comments, feel free to ignore :)
component/component.go
Outdated
func (id *InstanceID) PipelineIDs() map[ID]struct{} { | ||
return id.pipelineIDs | ||
} |
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.
Maybe it's over the top, but did you consider returning a copy of the map, to ensure the ID is truly immutable? Otherwise a caller can still modify the object.
I also wonder if it would be sensible to store the pipeline IDs in a way that makes the InstanceID type comparable. Again it doesn't seem to matter at the moment, since InstanceID is passed around by reference everywhere. Just thinking it could be good for future proofing.
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 had considered returning a copy of the map, but I wasn't sure it was worth the performance hit. These will be read often. This is an easy change to make though if anyone has strong opinions. Do you have a suggestion for how we might store PipelineIDs in a way that will make InstanceID comparable? If so, I'd be open to considering it. Bonus if it solves the true immutability problem as well.
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 had considered returning a copy of the map, but I wasn't sure it was worth the performance hit. These will be read often. This is an easy change to make though if anyone has strong opinions.
Fair enough. I don't have a very strong opinion on this, just stumbled on the PR and thought it would be worth checking.
Do you have a suggestion for how we might store PipelineIDs in a way that will make InstanceID comparable? If so, I'd be open to considering it. Bonus if it solves the true immutability problem as well.
One option would be to:
- marshal the IDs, with some separator (space?) that's not permitted in type or name, and store as a string
- change
PipelineIDs
to an iterator-type function likepcommon.Map.Range
which incrementally unmarshals the IDs
The range function could be written in a way that works with Go 1.23's upcoming iterator functions: https://pkg.go.dev/iter#hdr-Iterators
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.
Both of these properties seem to me like things that could be added in the future in a backwards compatible way. If anything, we can document now that this is not comparable and that the map should not be modified, and leave adding this extra guarantees for a future PR.
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.
Seems fine to me. Having map[ID]struct{}
in the exposed API doesn't seem ideal, and making it an iterator would be breaking again, but I don't think it's worth blocking over.
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.
making it an iterator would be breaking again, but I don't think it's worth blocking over.
I don't feel like it's incompatible to add a new method for the iterator if we ensure the data is presented in the same way. I'll wait for Matt to give his opinion as well :)
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.
@axw, I refactored the InstanceID to be comparable per your suggestions. Take a look and see if this is what you had in mind. Let me know if it needs any further work. I chose the second (or third) best name for the iterator to leave the door open to rename it (to AllPipelineIDs
or just PipelineIDs
) when we can use the iterator functions coming in Go 1.23.
5e7d9eb
to
214dc11
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.
component/component.go
Outdated
// InstanceID uniquely identifies a component instance | ||
// pipelineDelim is the delimeter for internal representation of pipeline | ||
// component IDs. | ||
const pipelineDelim = byte(0x20) |
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.
Unfortunately it turns out that IDs can contain a space :(
I mean I can define a receiver like this:
receivers:
"otlp/abc def":
protocols:
grpc:
endpoint: localhost:4317
http:
endpoint: localhost:4318
Even a null byte in the name is accepted.
Seems a little lax to me. Perhaps revert to a map for now, but keep the method change, and we could follow up on making the type comparable later after finding a way to safely encode the IDs? Could either use size prefixing (non-breaking), or add some restrictions to IDs (breaking, but maybe a good idea anyway).
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 already introduced restrictions on the part before the /
and had no user reports of it breaking them, so I would be in favor of doing the same for the name part (after the /
)
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 can take a look at adding the same restrictions to the name as we currently have on the type. If it's not terrible, maybe we can make both changes? If it turns out to be more work than expected, we can keep the iterator, and use a map internally, then make InstanceID comparable when we have restrictions on the name.
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 that makes sense to me
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 opened #10674 to handle restrictions to the name portion of a component.ID. The needs were slightly different so I introduced a different type for the name field.
#### Description While working on #10495 we discovered that there are not any restrictions on the `name` field of a `component.ID`. There are restrictions on the `type` field introduced in #9208. This PR adds similar restrictions to `name`. A type must - have at least one character, - start with an ASCII alphabetic character and - can only contain ASCII alphanumeric characters and '_'. I found that we need a slightly different set of rules for name as some tests use a digit and others use a uuid as a name. A name is still optional, but if it's provided it must: - have at least one character, - start with an ASCII alphanumeric character and - can only contain ASCII alphanumeric characters, '_', and '-'. I'd be willing to adjust these restrictions if anyone has any opinions on what should or should not be allowed. <!-- Issue number if applicable --> #### Link to tracking issue Fixes #10673 <!--Describe what testing was performed and which tests were added.--> #### Testing Unit tests <!--Describe the documentation added.--> #### Documentation Code comments <!--Please delete paragraphs that you did not use before submitting.-->
Can this move forward now that #10674 is merged? |
Good point, we can wait for #10777 |
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
This is now unblocked since I merged #10777 |
214dc11
to
c8d3033
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.
Changes look good to me, one nit. I didn't check why CI is failing on contrib.
Co-authored-by: Antoine Toulme <[email protected]>
This is expected to temporarily break contrib. It's a breaking change to the newly introduced componentstatus.InstanceID. This PR originally targeted component.InstanceID, put was put on hold to accommodate the component status refactor. I'll fix contrib when this merges. |
Co-authored-by: Tyler Helmuth <[email protected]>
Co-authored-by: Tyler Helmuth <[email protected]>
@mwear please take a look at the failing lint |
Description
This PR makes component.InstanceID immutable. Previously it was a struct with all fields exported. Technically this is a breaking change, but the only thing using the InstanceID is the in-progress healthcheckv2extension.
Link to tracking issue
Fixes #10494
Testing
units
Documentation
code comments