mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2024-12-30 21:20:04 +02:00
Guard rng in exemplar rand computation (#5456)
Fix #5455 The `math/rand.Rand` type is not safe for concurrent access. Concurrent measurements, and therefore concurrent exemplar computation, are allowed. Ensure this concurrent design does not lead to data races with `rng`.
This commit is contained in:
parent
d5a66e0e49
commit
047df28b88
@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
- Identify the `Meter` returned from the global `MeterProvider` in `go.opentelemetry.io/otel/global` with its schema URL. (#5426)
|
- Identify the `Meter` returned from the global `MeterProvider` in `go.opentelemetry.io/otel/global` with its schema URL. (#5426)
|
||||||
- Log a warning to the OpenTelemetry internal logger when a `Span` in `go.opentelemetry.io/otel/sdk/trace` drops an attribute, event, or link due to a limit being reached. (#5434)
|
- Log a warning to the OpenTelemetry internal logger when a `Span` in `go.opentelemetry.io/otel/sdk/trace` drops an attribute, event, or link due to a limit being reached. (#5434)
|
||||||
- Document instrument name requirements in `go.opentelemetry.io/otel/metric`. (#5435)
|
- Document instrument name requirements in `go.opentelemetry.io/otel/metric`. (#5435)
|
||||||
|
- Prevent random number generation data-race for experimental rand exemplars in `go.opentelemetry.io/otel/sdk/metric`. (#5456)
|
||||||
|
|
||||||
## [1.27.0/0.49.0/0.3.0] 2024-05-21
|
## [1.27.0/0.49.0/0.3.0] 2024-05-21
|
||||||
|
|
||||||
|
@ -7,16 +7,21 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
)
|
)
|
||||||
|
|
||||||
// rng is used to make sampling decisions.
|
var (
|
||||||
//
|
// rng is used to make sampling decisions.
|
||||||
// Do not use crypto/rand. There is no reason for the decrease in performance
|
//
|
||||||
// given this is not a security sensitive decision.
|
// Do not use crypto/rand. There is no reason for the decrease in performance
|
||||||
var rng = rand.New(rand.NewSource(time.Now().UnixNano()))
|
// given this is not a security sensitive decision.
|
||||||
|
rng = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
// Ensure concurrent safe accecess to rng and its underlying source.
|
||||||
|
rngMu sync.Mutex
|
||||||
|
)
|
||||||
|
|
||||||
// random returns, as a float64, a uniform pseudo-random number in the open
|
// random returns, as a float64, a uniform pseudo-random number in the open
|
||||||
// interval (0.0,1.0).
|
// interval (0.0,1.0).
|
||||||
@ -38,6 +43,9 @@ func random() float64 {
|
|||||||
//
|
//
|
||||||
// There are likely many other methods to explore here as well.
|
// There are likely many other methods to explore here as well.
|
||||||
|
|
||||||
|
rngMu.Lock()
|
||||||
|
defer rngMu.Unlock()
|
||||||
|
|
||||||
f := rng.Float64()
|
f := rng.Float64()
|
||||||
for f == 0 {
|
for f == 0 {
|
||||||
f = rng.Float64()
|
f = rng.Float64()
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"math"
|
"math"
|
||||||
"slices"
|
"slices"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -49,3 +50,18 @@ func TestFixedSizeSamplingCorrectness(t *testing.T) {
|
|||||||
// ensuring no bias in our random sampling algorithm.
|
// ensuring no bias in our random sampling algorithm.
|
||||||
assert.InDelta(t, 1/mean, intensity, 0.02) // Within 5σ.
|
assert.InDelta(t, 1/mean, intensity, 0.02) // Within 5σ.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRandomConcurrentSafe(t *testing.T) {
|
||||||
|
const goRoutines = 10
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for n := 0; n < goRoutines; n++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
_ = random()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user