Spec requirement
All ExemplarReservoir methods MUST be safe for concurrent use (sdk.md:1984-2001, Concurrency requirements).
Current behavior
SimpleFixedSizeExemplarReservoir and AlignedHistogramBucketExemplarReservoir (exemplar/simple_fixed_size_exemplar_reservoir.rb (permalink), exemplar/aligned_histogram_bucket_exemplar_reservoir.rb (permalink)) have no internal locking — their @num_measurements_seen/bucket-array mutation in #offer is unsynchronized, relying entirely on the caller (MetricStream#update, itself mutex-guarded per-stream) to serialize access. This holds for the shipped call path but isn't a property of the reservoir classes themselves, as the spec requires.
Suggested fix
Add a mutex around the mutable state in both reservoir implementations' #offer/#collect methods, so they're safe even if called from outside the one guarded call path the SDK currently uses.
Related rows in SPEC_COMPLIANCE_METRICS.md
SDK-65
Spec requirement
All
ExemplarReservoirmethods MUST be safe for concurrent use (sdk.md:1984-2001, Concurrency requirements).Current behavior
SimpleFixedSizeExemplarReservoirandAlignedHistogramBucketExemplarReservoir(exemplar/simple_fixed_size_exemplar_reservoir.rb(permalink),exemplar/aligned_histogram_bucket_exemplar_reservoir.rb(permalink)) have no internal locking — their@num_measurements_seen/bucket-array mutation in#offeris unsynchronized, relying entirely on the caller (MetricStream#update, itself mutex-guarded per-stream) to serialize access. This holds for the shipped call path but isn't a property of the reservoir classes themselves, as the spec requires.Suggested fix
Add a mutex around the mutable state in both reservoir implementations'
#offer/#collectmethods, so they're safe even if called from outside the one guarded call path the SDK currently uses.Related rows in SPEC_COMPLIANCE_METRICS.md
SDK-65