Skip to content

Commit 3c1286a

Browse files
MrAliaspellared
andauthored
Document and check resource comparability (#6272)
Ensure backwards compatibility by adding a compile-time check that the Resource remains comparable. Document the shortcomings of direct comparison of a Resource. --------- Co-authored-by: Robert Pająk <[email protected]>
1 parent afbe545 commit 3c1286a

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2525
- The `go.opentelemetry.io/otel/semconv/v1.30.0` package.
2626
The package contains semantic conventions from the `v1.30.0` version of the OpenTelemetry Semantic Conventions.
2727
See the [migration documentation](./semconv/v1.30.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.28.0`(#6240)
28+
- Document the pitfalls of using `Resource` as a comparable type.
29+
`Resource.Equal` and `Resource.Equivalent` should be used instead. (#6272)
2830

2931
### Changed
3032

sdk/resource/resource.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,22 @@ import (
2121
// Resources should be passed and stored as pointers
2222
// (`*resource.Resource`). The `nil` value is equivalent to an empty
2323
// Resource.
24+
//
25+
// Note that the Go == operator compares not just the resource attributes but
26+
// also all other internals of the Resource type. Therefore, Resource values
27+
// should not be used as map or database keys. In general, the [Resource.Equal]
28+
// method should be used instead of direct comparison with ==, since that
29+
// method ensures the correct comparison of resource attributes, and the
30+
// [attribute.Distinct] returned from [Resource.Equivalent] should be used for
31+
// map and database keys instead.
2432
type Resource struct {
2533
attrs attribute.Set
2634
schemaURL string
2735
}
2836

37+
// Compile-time check that the Resource remains comparable.
38+
var _ map[Resource]struct{} = nil
39+
2940
var (
3041
defaultResource *Resource
3142
defaultResourceOnce sync.Once
@@ -137,15 +148,19 @@ func (r *Resource) Iter() attribute.Iterator {
137148
return r.attrs.Iter()
138149
}
139150

140-
// Equal returns true when a Resource is equivalent to this Resource.
141-
func (r *Resource) Equal(eq *Resource) bool {
151+
// Equal returns whether r and o represent the same resource. Two resources can
152+
// be equal even if they have different schema URLs.
153+
//
154+
// See the documentation on the [Resource] type for the pitfalls of using ==
155+
// with Resource values; most code should use Equal instead.
156+
func (r *Resource) Equal(o *Resource) bool {
142157
if r == nil {
143158
r = Empty()
144159
}
145-
if eq == nil {
146-
eq = Empty()
160+
if o == nil {
161+
o = Empty()
147162
}
148-
return r.Equivalent() == eq.Equivalent()
163+
return r.Equivalent() == o.Equivalent()
149164
}
150165

151166
// Merge creates a new [Resource] by merging a and b.

0 commit comments

Comments
 (0)