Skip to content

Commit fb2d5bf

Browse files
committed
rawvalue: fix thread safety and sum
1 parent a1546ad commit fb2d5bf

File tree

4 files changed

+67
-8
lines changed

4 files changed

+67
-8
lines changed

go.mod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
module github.com/spacemonkeygo/monkit/v3
22

3-
go 1.19
3+
go 1.23.0
4+
5+
toolchain go1.24.3
6+
7+
require golang.org/x/sync v0.14.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
2+
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=

val.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,28 @@ func (v *RawVal) Observe(val float64) {
291291

292292
// Stats implements the StatSource interface.
293293
func (v *RawVal) Stats(cb func(key SeriesKey, field string, val float64)) {
294+
type datum struct {
295+
field string
296+
value float64
297+
}
298+
var data []datum
299+
if len(v.stats) < 8 {
300+
var buf [8]datum
301+
data = buf[:len(v.stats)]
302+
} else {
303+
data = make([]datum, len(v.stats))
304+
}
294305
v.mtx.Lock()
295-
cb(v.key, "recent", v.value)
296-
v.mtx.Unlock()
297-
for _, s := range v.stats {
306+
for i, s := range v.stats {
298307
field, value := s()
299-
cb(v.key, field, value)
308+
data[i] = datum{field, value}
309+
}
310+
recent := v.value
311+
v.mtx.Unlock()
312+
313+
cb(v.key, "recent", recent)
314+
for _, d := range data {
315+
cb(v.key, d.field, d.value)
300316
}
301317
}
302318

@@ -320,10 +336,10 @@ func Count() (observe func(val float64), stat func() (field string, val float64)
320336

321337
// Sum is a value aggregator that summarizes the values measured.
322338
func Sum() (observe func(val float64), stat func() (field string, val float64)) {
323-
var sum int
339+
var sum float64
324340
return func(val float64) {
325-
sum += int(val)
341+
sum += val
326342
}, func() (field string, val float64) {
327-
return "sum", float64(sum)
343+
return "sum", sum
328344
}
329345
}

val_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (C) 2015 Space Monkey, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package monkit
16+
17+
import (
18+
"golang.org/x/sync/errgroup"
19+
"testing"
20+
)
21+
22+
func TestRawValConcurrentSafe(t *testing.T) {
23+
rv := NewRawVal(NewSeriesKey("test"), Sum, Count)
24+
25+
var group errgroup.Group
26+
defer func() { _ = group.Wait() }()
27+
for i := 0; i < 10; i++ {
28+
group.Go(func() error {
29+
if i%2 == 0 {
30+
rv.Observe(1.0)
31+
} else {
32+
rv.Stats(func(key SeriesKey, field string, val float64) {})
33+
}
34+
return nil
35+
})
36+
}
37+
}

0 commit comments

Comments
 (0)