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

[component] Make InstanceID immutable #10495

Merged
merged 8 commits into from
Aug 21, 2024

Conversation

mwear
Copy link
Member

@mwear mwear commented Jul 1, 2024

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

Copy link

codecov bot commented Jul 1, 2024

Codecov Report

Attention: Patch coverage is 93.10345% with 4 lines in your changes missing coverage. Please review.

Project coverage is 91.67%. Comparing base (fce1d46) to head (83dcd9d).
Report is 13 commits behind head on main.

Files Patch % Lines
component/componentstatus/instance.go 89.47% 4 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

component/component.go Outdated Show resolved Hide resolved
component/component.go Outdated Show resolved Hide resolved
Copy link
Member

@mx-psi mx-psi left a 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

@mwear
Copy link
Member Author

mwear commented Jul 17, 2024

I'll get on those issues and bring this out of draft and rebase.

@mwear
Copy link
Member Author

mwear commented Jul 17, 2024

Copy link
Contributor

@axw axw left a 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 :)

Comment on lines 224 to 226
func (id *InstanceID) PipelineIDs() map[ID]struct{} {
return id.pipelineIDs
}
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

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 like pcommon.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

Copy link
Member

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.

Copy link
Contributor

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.

Copy link
Member

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 :)

Copy link
Member Author

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.

@mwear mwear force-pushed the immutable-instance-id branch 2 times, most recently from 5e7d9eb to 214dc11 Compare July 18, 2024 23:33
Copy link
Contributor

@axw axw left a comment

Choose a reason for hiding this comment

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

@mwear looks great, and exactly what I meant, but I just tested locally and found that IDs can have spaces in them. I'd be inclined to revert to using a map internally, and follow up on making it comparable later as @mx-psi suggested. Sorry for the diversion.

// InstanceID uniquely identifies a component instance
// pipelineDelim is the delimeter for internal representation of pipeline
// component IDs.
const pipelineDelim = byte(0x20)
Copy link
Contributor

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).

Copy link
Member

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 /)

Copy link
Member Author

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.

Copy link
Member

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

Copy link
Member Author

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.

mx-psi pushed a commit that referenced this pull request Jul 25, 2024
#### 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.-->
@mx-psi
Copy link
Member

mx-psi commented Jul 31, 2024

Can this move forward now that #10674 is merged?

@mwear
Copy link
Member Author

mwear commented Jul 31, 2024

Can this move forward now that #10674 is merged?

This can move forward, but now that #10730 has merged, I'm wondering if I should update componentstatus.InstanceID instead and what the order of operations should be given #10777.

@mx-psi
Copy link
Member

mx-psi commented Aug 1, 2024

Good point, we can wait for #10777

Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions github-actions bot added the Stale label Aug 16, 2024
@mx-psi mx-psi removed the Stale label Aug 16, 2024
@mx-psi
Copy link
Member

mx-psi commented Aug 16, 2024

This is now unblocked since I merged #10777

Copy link
Contributor

@atoulme atoulme left a 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.

@mwear
Copy link
Member Author

mwear commented Aug 16, 2024

Changes look good to me, one nit. I didn't check why CI is failing on contrib.

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.

.chloggen/immutable-instance-id.yaml Outdated Show resolved Hide resolved
component/componentstatus/instance.go Outdated Show resolved Hide resolved
.chloggen/immutable-instance-id.yaml Outdated Show resolved Hide resolved
@TylerHelmuth
Copy link
Member

@mwear please take a look at the failing lint

@mx-psi mx-psi merged commit 98fb888 into open-telemetry:main Aug 21, 2024
35 of 36 checks passed
@github-actions github-actions bot added this to the next release milestone Aug 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[component] Make InstanceID immutable
6 participants