Codebase list golang-github-go-kit-kit / f2e95e8
metrics/generic: make VividCortex/gohistogram safe Peter Bourgon 7 years ago
2 changed file(s) with 36 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
120120 type Histogram struct {
121121 Name string
122122 lvs lv.LabelValues
123 h gohistogram.Histogram
123 h *safeHistogram
124124 }
125125
126126 // NewHistogram returns a numeric histogram based on VividCortex/gohistogram. A
128128 func NewHistogram(name string, buckets int) *Histogram {
129129 return &Histogram{
130130 Name: name,
131 h: gohistogram.NewHistogram(buckets),
131 h: &safeHistogram{Histogram: gohistogram.NewHistogram(buckets)},
132132 }
133133 }
134134
142142
143143 // Observe implements Histogram.
144144 func (h *Histogram) Observe(value float64) {
145 h.h.Lock()
146 defer h.h.Unlock()
145147 h.h.Add(value)
146148 }
147149
148150 // Quantile returns the value of the quantile q, 0.0 < q < 1.0.
149151 func (h *Histogram) Quantile(q float64) float64 {
152 h.h.RLock()
153 defer h.h.RUnlock()
150154 return h.h.Quantile(q)
151155 }
152156
158162 // Print writes a string representation of the histogram to the passed writer.
159163 // Useful for printing to a terminal.
160164 func (h *Histogram) Print(w io.Writer) {
165 h.h.RLock()
166 defer h.h.RUnlock()
161167 fmt.Fprintf(w, h.h.String())
168 }
169
170 // safeHistogram exists as gohistogram.Histogram is not goroutine-safe.
171 type safeHistogram struct {
172 sync.RWMutex
173 gohistogram.Histogram
162174 }
163175
164176 // Bucket is a range in a histogram which aggregates observations.
66 import (
77 "math"
88 "math/rand"
9 "sync"
910 "testing"
1011
1112 "github.com/go-kit/kit/metrics/generic"
5152 }
5253 }
5354
55 func TestIssue424(t *testing.T) {
56 var (
57 histogram = generic.NewHistogram("dont_panic", 50)
58 concurrency = 100
59 operations = 1000
60 wg sync.WaitGroup
61 )
62
63 wg.Add(concurrency)
64 for i := 0; i < concurrency; i++ {
65 go func() {
66 defer wg.Done()
67 for j := 0; j < operations; j++ {
68 histogram.Observe(float64(j))
69 histogram.Observe(histogram.Quantile(0.5))
70 }
71 }()
72 }
73 wg.Wait()
74 }
75
5476 func TestSimpleHistogram(t *testing.T) {
5577 histogram := generic.NewSimpleHistogram().With("label", "simple_histogram").(*generic.SimpleHistogram)
5678 var (