Skip to content

refactor: replace uber atomic with stdlib atomic types (Issue #14866)#17358

Open
Gokula-6sg wants to merge 3 commits intoprometheus:mainfrom
Gokula-6sg:replace-uber-atomics
Open

refactor: replace uber atomic with stdlib atomic types (Issue #14866)#17358
Gokula-6sg wants to merge 3 commits intoprometheus:mainfrom
Gokula-6sg:replace-uber-atomics

Conversation

@Gokula-6sg
Copy link

@Gokula-6sg Gokula-6sg commented Oct 17, 2025

Which issue(s) does the PR fix:

  • Replaces go.uber.org/atomic with stdlib sync/atomic.

Does this PR introduce a user-facing change?

[ENHANCEMENT] core: Migrate from go.uber.org/atomic to sync/atomic, removing external dependency

.golangci.yml Outdated
@@ -84,7 +84,7 @@ linters:
main:
deny:
- pkg: "sync/atomic"
Copy link

Choose a reason for hiding this comment

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

You should also replace this with "go.uber.org/atomic"

Copy link
Author

@Gokula-6sg Gokula-6sg Oct 18, 2025

Choose a reason for hiding this comment

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

Thanks for catching that! I've updated the .golangci.yml to deny go.uber.org/atomic instead of sync/atomic.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the clarification! I’ve updated .golangci.yml as suggested. I’ll run make lint locally to verify everything passes before pushing the changes.

// Wait until the mock server receives at least two requests from Prometheus.
require.Eventually(t, func() bool {
return requestCount.Load() >= 2
return atomic.LoadInt32(&requestCount) >= 2
Copy link

Choose a reason for hiding this comment

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

Was there a reason why you used atomic.LoadInt32() instead of leaving requestCount as atomic.Int32 and using the Load() function here? According to the documentation, Consider using the more ergonomic and less error-prone Int32.Load instead., it's preferable to use the Load() function.

Copy link
Member

Choose a reason for hiding this comment

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

Agreed, this is the wrong way to go.

func (r *AlertingRule) SetLastError(err error) {
r.lastError.Store(err)
if err != nil {
r.lastError.Store(err)
Copy link

Choose a reason for hiding this comment

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

I'm not sure it's a good idea to ignore nil values. To avoid panic during Store(), you can use a wrapper structure that can contains a nil value. You can write a utility structure in utils/atomicutils using generics, which will eliminate two problems at once: storing nil values ​​and safely casting types during Load(). You can take a look at the implementation in my branch. It might not be perfect either, so feel free to modify it.

@adity-a34
Copy link
Contributor

Hi @Gokula-6sg ,
The workflow seems to be failing.
Please fix it...for lint issue you may use make lint to resolve it.

Copy link
Member

@bboreham bboreham left a comment

Choose a reason for hiding this comment

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

Thanks for doing this. Seems there are a few corners to explore still.

toolkit_web "github.com/prometheus/exporter-toolkit/web"
"go.uber.org/atomic"
"sync/atomic"

Copy link
Member

Choose a reason for hiding this comment

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

spurious blank line

// Wait until the mock server receives at least two requests from Prometheus.
require.Eventually(t, func() bool {
return requestCount.Load() >= 2
return atomic.LoadInt32(&requestCount) >= 2
Copy link
Member

Choose a reason for hiding this comment

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

Agreed, this is the wrong way to go.

Comment on lines +509 to +519
addSamplesTotal := func(delta float64) {
for {
oldBits := samplesTotal.Load()
oldVal := math.Float64frombits(oldBits)
newVal := oldVal + delta
newBits := math.Float64bits(newVal)
if samplesTotal.CompareAndSwap(oldBits, newBits) {
break
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This seems over-complicated. Just add the int which comes from len. samplesTotal should be fine as a Uint64.

(series.lastHistogramValue != nil && value.IsStaleNaN(series.lastHistogramValue.Sum)) ||
(series.lastFloatHistogramValue != nil && value.IsStaleNaN(series.lastFloatHistogramValue.Sum)) {
numStaleSeries.Dec()
numStaleSeries.Add(^uint64(0)) // Equivalent to -1 for unsigned overflow
Copy link
Member

Choose a reason for hiding this comment

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

Make it an atomic.Int64 then you can Add(-1) and save explaining.

@aknuds1
Copy link
Contributor

aknuds1 commented Dec 21, 2025

Can you rebase this on main please @Gokula-6sg?

@bboreham
Copy link
Member

Hello from the bug-scrub! @Gokula-6sg do you think you will come back to this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants