Verified Commit 418f76dc authored by Cecylia Bocovich's avatar Cecylia Bocovich 💬
Browse files

Use a mutex to fix data races in safeprom counter

The multi-step logic around incrementing the safeprom counter
(incrementing the current true count, checking whether it exceeds the
current rounded count, and incrementing the rounded count), this code is
not well suited for atomic operations. Instead, this change surrounds
the Inc() and Write() functions with a sync.Mutex lock.
parent a01861f6
Loading
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ counts of users and proxies
package safeprom

import (
	"sync/atomic"
	"sync"

	"github.com/prometheus/client_golang/prometheus"
	dto "github.com/prometheus/client_model/go"
@@ -25,15 +25,19 @@ type counter struct {
	total uint64 //reflects the true count
	value uint64 //reflects the rounded count

	lock sync.Mutex

	desc       *prometheus.Desc
	labelPairs []*dto.LabelPair
}

// Implements the Counter interface
func (c *counter) Inc() {
	atomic.AddUint64(&c.total, 1)
	c.lock.Lock()
	defer c.lock.Unlock()
	c.total++
	if c.total > c.value {
		atomic.AddUint64(&c.value, 8)
		c.value += 8
	}
}

@@ -44,6 +48,8 @@ func (c *counter) Desc() *prometheus.Desc {

// Implements the prometheus.Metric interface
func (c *counter) Write(m *dto.Metric) error {
	c.lock.Lock()
	defer c.lock.Unlock()
	m.Label = c.labelPairs

	m.Counter = &dto.Counter{Value: proto.Float64(float64(c.value))}