1
1
package metrics
2
2
3
3
import (
4
+ "math"
4
5
"sync"
6
+ "sync/atomic"
5
7
"time"
6
8
)
7
9
@@ -62,7 +64,7 @@ func NewRegisteredMeter(name string, r Registry) Meter {
62
64
// MeterSnapshot is a read-only copy of another Meter.
63
65
type MeterSnapshot struct {
64
66
count int64
65
- rate1 , rate5 , rate15 , rateMean float64
67
+ rate1 , rate5 , rate15 , rateMean uint64
66
68
}
67
69
68
70
// Count returns the count of events at the time the snapshot was taken.
@@ -75,19 +77,19 @@ func (*MeterSnapshot) Mark(n int64) {
75
77
76
78
// Rate1 returns the one-minute moving average rate of events per second at the
77
79
// time the snapshot was taken.
78
- func (m * MeterSnapshot ) Rate1 () float64 { return m .rate1 }
80
+ func (m * MeterSnapshot ) Rate1 () float64 { return math . Float64frombits ( m .rate1 ) }
79
81
80
82
// Rate5 returns the five-minute moving average rate of events per second at
81
83
// the time the snapshot was taken.
82
- func (m * MeterSnapshot ) Rate5 () float64 { return m .rate5 }
84
+ func (m * MeterSnapshot ) Rate5 () float64 { return math . Float64frombits ( m .rate5 ) }
83
85
84
86
// Rate15 returns the fifteen-minute moving average rate of events per second
85
87
// at the time the snapshot was taken.
86
- func (m * MeterSnapshot ) Rate15 () float64 { return m .rate15 }
88
+ func (m * MeterSnapshot ) Rate15 () float64 { return math . Float64frombits ( m .rate15 ) }
87
89
88
90
// RateMean returns the meter's mean rate of events per second at the time the
89
91
// snapshot was taken.
90
- func (m * MeterSnapshot ) RateMean () float64 { return m .rateMean }
92
+ func (m * MeterSnapshot ) RateMean () float64 { return math . Float64frombits ( m .rateMean ) }
91
93
92
94
// Snapshot returns the snapshot.
93
95
func (m * MeterSnapshot ) Snapshot () Meter { return m }
@@ -124,7 +126,8 @@ func (NilMeter) Stop() {}
124
126
125
127
// StandardMeter is the standard implementation of a Meter.
126
128
type StandardMeter struct {
127
- lock sync.RWMutex
129
+ // Only used on stop.
130
+ lock sync.Mutex
128
131
snapshot * MeterSnapshot
129
132
a1 , a5 , a15 EWMA
130
133
startTime time.Time
@@ -156,10 +159,7 @@ func (m *StandardMeter) Stop() {
156
159
157
160
// Count returns the number of events recorded.
158
161
func (m * StandardMeter ) Count () int64 {
159
- m .lock .RLock ()
160
- count := m .snapshot .count
161
- m .lock .RUnlock ()
162
- return count
162
+ return atomic .LoadInt64 (& m .snapshot .count )
163
163
}
164
164
165
165
// Mark records the occurance of n events.
@@ -178,56 +178,49 @@ func (m *StandardMeter) Mark(n int64) {
178
178
179
179
// Rate1 returns the one-minute moving average rate of events per second.
180
180
func (m * StandardMeter ) Rate1 () float64 {
181
- m .lock .RLock ()
182
- rate1 := m .snapshot .rate1
183
- m .lock .RUnlock ()
184
- return rate1
181
+ return math .Float64frombits (atomic .LoadUint64 (& m .snapshot .rate1 ))
185
182
}
186
183
187
184
// Rate5 returns the five-minute moving average rate of events per second.
188
185
func (m * StandardMeter ) Rate5 () float64 {
189
- m .lock .RLock ()
190
- rate5 := m .snapshot .rate5
191
- m .lock .RUnlock ()
192
- return rate5
186
+ return math .Float64frombits (atomic .LoadUint64 (& m .snapshot .rate5 ))
193
187
}
194
188
195
189
// Rate15 returns the fifteen-minute moving average rate of events per second.
196
190
func (m * StandardMeter ) Rate15 () float64 {
197
- m .lock .RLock ()
198
- rate15 := m .snapshot .rate15
199
- m .lock .RUnlock ()
200
- return rate15
191
+ return math .Float64frombits (atomic .LoadUint64 (& m .snapshot .rate15 ))
201
192
}
202
193
203
194
// RateMean returns the meter's mean rate of events per second.
204
195
func (m * StandardMeter ) RateMean () float64 {
205
- m .lock .RLock ()
206
- rateMean := m .snapshot .rateMean
207
- m .lock .RUnlock ()
208
- return rateMean
196
+ return math .Float64frombits (atomic .LoadUint64 (& m .snapshot .rateMean ))
209
197
}
210
198
211
199
// Snapshot returns a read-only copy of the meter.
212
200
func (m * StandardMeter ) Snapshot () Meter {
213
- m .lock .RLock ()
214
- snapshot := * m .snapshot
215
- m .lock .RUnlock ()
216
- return & snapshot
201
+ copiedSnapshot := MeterSnapshot {
202
+ count : atomic .LoadInt64 (& m .snapshot .count ),
203
+ rate1 : atomic .LoadUint64 (& m .snapshot .rate1 ),
204
+ rate5 : atomic .LoadUint64 (& m .snapshot .rate5 ),
205
+ rate15 : atomic .LoadUint64 (& m .snapshot .rate15 ),
206
+ rateMean : atomic .LoadUint64 (& m .snapshot .rateMean ),
207
+ }
208
+ return & copiedSnapshot
217
209
}
218
210
219
211
func (m * StandardMeter ) updateSnapshot () {
220
- // should run with write lock held on m.lock
221
- snapshot := m .snapshot
222
- snapshot .rate1 = m .a1 .Rate ()
223
- snapshot .rate5 = m .a5 .Rate ()
224
- snapshot .rate15 = m .a15 .Rate ()
225
- snapshot .rateMean = float64 (snapshot .count ) / time .Since (m .startTime ).Seconds ()
212
+ rate1 := math .Float64bits (m .a1 .Rate ())
213
+ rate5 := math .Float64bits (m .a5 .Rate ())
214
+ rate15 := math .Float64bits (m .a15 .Rate ())
215
+ rateMean := math .Float64bits (float64 (m .Count ()) / time .Since (m .startTime ).Seconds ())
216
+
217
+ atomic .StoreUint64 (& m .snapshot .rate1 , rate1 )
218
+ atomic .StoreUint64 (& m .snapshot .rate5 , rate5 )
219
+ atomic .StoreUint64 (& m .snapshot .rate15 , rate15 )
220
+ atomic .StoreUint64 (& m .snapshot .rateMean , rateMean )
226
221
}
227
222
228
223
func (m * StandardMeter ) tick () {
229
- m .lock .Lock ()
230
- defer m .lock .Unlock ()
231
224
m .a1 .Tick ()
232
225
m .a5 .Tick ()
233
226
m .a15 .Tick ()
0 commit comments