gauge.go: add Inc, Dec and Add methods to Gauge
This commit is contained in:
parent
fdfd428a62
commit
da211e52b9
34
gauge.go
34
gauge.go
@ -17,7 +17,7 @@ import (
|
||||
// - foo{bar="baz",aaa="b"}
|
||||
//
|
||||
// f must be safe for concurrent calls.
|
||||
// if f is nil, then it is expected that the gauge value is changed via Gauge.Set() call.
|
||||
// if f is nil, then it is expected that the gauge value is changed via Set(), Inc(), Dec() and Add() calls.
|
||||
//
|
||||
// The returned gauge is safe to use from concurrent goroutines.
|
||||
//
|
||||
@ -55,6 +55,38 @@ func (g *Gauge) Set(v float64) {
|
||||
atomic.StoreUint64(&g.valueBits, n)
|
||||
}
|
||||
|
||||
// Inc increments g by 1.
|
||||
//
|
||||
// The g must be created with nil callback in order to be able to call this function.
|
||||
func (g *Gauge) Inc() {
|
||||
g.Add(1)
|
||||
}
|
||||
|
||||
// Dec decrements g by 1.
|
||||
//
|
||||
// The g must be created with nil callback in order to be able to call this function.
|
||||
func (g *Gauge) Dec() {
|
||||
g.Add(-1)
|
||||
}
|
||||
|
||||
// Add adds fAdd to g. fAdd may be positive and negative.
|
||||
//
|
||||
// The g must be created with nil callback in order to be able to call this function.
|
||||
func (g *Gauge) Add(fAdd float64) {
|
||||
if g.f != nil {
|
||||
panic(fmt.Errorf("cannot call Set on gauge created with non-nil callback"))
|
||||
}
|
||||
for {
|
||||
n := atomic.LoadUint64(&g.valueBits)
|
||||
f := math.Float64frombits(n)
|
||||
fNew := f + fAdd
|
||||
nNew := math.Float64bits(fNew)
|
||||
if atomic.CompareAndSwapUint64(&g.valueBits, n, nNew) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Gauge) marshalTo(prefix string, w io.Writer) {
|
||||
v := g.Get()
|
||||
if float64(int64(v)) == v {
|
||||
|
@ -15,6 +15,18 @@ func TestGaugeError(t *testing.T) {
|
||||
g := GetOrCreateGauge("GetOrCreateGauge_nil_callback", func() float64 { return 123 })
|
||||
g.Set(42)
|
||||
})
|
||||
expectPanic(t, "GetOrCreateGauge_Add_non-nil-callback", func() {
|
||||
g := GetOrCreateGauge("GetOrCreateGauge_nil_callback", func() float64 { return 123 })
|
||||
g.Add(42)
|
||||
})
|
||||
expectPanic(t, "GetOrCreateGauge_Inc_non-nil-callback", func() {
|
||||
g := GetOrCreateGauge("GetOrCreateGauge_nil_callback", func() float64 { return 123 })
|
||||
g.Inc()
|
||||
})
|
||||
expectPanic(t, "GetOrCreateGauge_Dec_non-nil-callback", func() {
|
||||
g := GetOrCreateGauge("GetOrCreateGauge_nil_callback", func() float64 { return 123 })
|
||||
g.Dec()
|
||||
})
|
||||
}
|
||||
|
||||
func TestGaugeSet(t *testing.T) {
|
||||
@ -29,6 +41,49 @@ func TestGaugeSet(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGaugeIncDec(t *testing.T) {
|
||||
s := NewSet()
|
||||
g := s.NewGauge("foo", nil)
|
||||
if n := g.Get(); n != 0 {
|
||||
t.Fatalf("unexpected gauge value: %g; expecting 0", n)
|
||||
}
|
||||
for i := 1; i <= 100; i++ {
|
||||
g.Inc()
|
||||
if n := g.Get(); n != float64(i) {
|
||||
t.Fatalf("unexpected gauge value %g; expecting %d", n, i)
|
||||
}
|
||||
}
|
||||
for i := 99; i >= 0; i-- {
|
||||
g.Dec()
|
||||
if n := g.Get(); n != float64(i) {
|
||||
t.Fatalf("unexpected gauge value %g; expecting %d", n, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGaugeIncDecConcurrenc(t *testing.T) {
|
||||
s := NewSet()
|
||||
g := s.NewGauge("foo", nil)
|
||||
|
||||
workers := 5
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < workers; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
for i := 0; i < 100; i++ {
|
||||
g.Inc()
|
||||
g.Dec()
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
if n := g.Get(); n != 0 {
|
||||
t.Fatalf("unexpected gauge value %g; want 0", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGaugeSerial(t *testing.T) {
|
||||
name := "GaugeSerial"
|
||||
n := 1.23
|
||||
|
Loading…
x
Reference in New Issue
Block a user