@@ -2,6 +2,7 @@ package metrics
2
2
3
3
import (
4
4
"sync"
5
+ "sync/atomic"
5
6
"time"
6
7
)
7
8
@@ -101,6 +102,7 @@ func NewRegisteredMeterForced(name string, r Registry) Meter {
101
102
// MeterSnapshot is a read-only copy of another Meter.
102
103
type MeterSnapshot struct {
103
104
count int64
105
+ temp int64
104
106
rate1 , rate5 , rate15 , rateMean float64
105
107
}
106
108
@@ -149,7 +151,7 @@ func (NilMeter) Rate1() float64 { return 0.0 }
149
151
// Rate5 is a no-op.
150
152
func (NilMeter ) Rate5 () float64 { return 0.0 }
151
153
152
- // Rate15is a no-op.
154
+ // Rate15 is a no-op.
153
155
func (NilMeter ) Rate15 () float64 { return 0.0 }
154
156
155
157
// RateMean is a no-op.
@@ -167,7 +169,7 @@ type StandardMeter struct {
167
169
snapshot * MeterSnapshot
168
170
a1 , a5 , a15 EWMA
169
171
startTime time.Time
170
- stopped bool
172
+ stopped uint32
171
173
}
172
174
173
175
func newStandardMeter () * StandardMeter {
@@ -182,69 +184,54 @@ func newStandardMeter() *StandardMeter {
182
184
183
185
// Stop stops the meter, Mark() will be a no-op if you use it after being stopped.
184
186
func (m * StandardMeter ) Stop () {
185
- m .lock .Lock ()
186
- stopped := m .stopped
187
- m .stopped = true
188
- m .lock .Unlock ()
189
- if ! stopped {
187
+ stopped := atomic .SwapUint32 (& m .stopped , 1 )
188
+ if stopped != 1 {
190
189
arbiter .Lock ()
191
190
delete (arbiter .meters , m )
192
191
arbiter .Unlock ()
193
192
}
194
193
}
195
194
196
195
// Count returns the number of events recorded.
196
+ // It updates the meter to be as accurate as possible
197
197
func (m * StandardMeter ) Count () int64 {
198
- m .lock .RLock ()
199
- count := m . snapshot . count
200
- m .lock . RUnlock ()
201
- return count
198
+ m .lock .Lock ()
199
+ defer m . lock . Unlock ()
200
+ m .updateMeter ()
201
+ return m . snapshot . count
202
202
}
203
203
204
204
// Mark records the occurrence of n events.
205
205
func (m * StandardMeter ) Mark (n int64 ) {
206
- m .lock .Lock ()
207
- defer m .lock .Unlock ()
208
- if m .stopped {
209
- return
210
- }
211
- m .snapshot .count += n
212
- m .a1 .Update (n )
213
- m .a5 .Update (n )
214
- m .a15 .Update (n )
215
- m .updateSnapshot ()
206
+ atomic .AddInt64 (& m .snapshot .temp , n )
216
207
}
217
208
218
209
// Rate1 returns the one-minute moving average rate of events per second.
219
210
func (m * StandardMeter ) Rate1 () float64 {
220
211
m .lock .RLock ()
221
- rate1 := m .snapshot .rate1
222
- m .lock .RUnlock ()
223
- return rate1
212
+ defer m .lock .RUnlock ()
213
+ return m .snapshot .rate1
224
214
}
225
215
226
216
// Rate5 returns the five-minute moving average rate of events per second.
227
217
func (m * StandardMeter ) Rate5 () float64 {
228
218
m .lock .RLock ()
229
- rate5 := m .snapshot .rate5
230
- m .lock .RUnlock ()
231
- return rate5
219
+ defer m .lock .RUnlock ()
220
+ return m .snapshot .rate5
232
221
}
233
222
234
223
// Rate15 returns the fifteen-minute moving average rate of events per second.
235
224
func (m * StandardMeter ) Rate15 () float64 {
236
225
m .lock .RLock ()
237
- rate15 := m .snapshot .rate15
238
- m .lock .RUnlock ()
239
- return rate15
226
+ defer m .lock .RUnlock ()
227
+ return m .snapshot .rate15
240
228
}
241
229
242
230
// RateMean returns the meter's mean rate of events per second.
243
231
func (m * StandardMeter ) RateMean () float64 {
244
232
m .lock .RLock ()
245
- rateMean := m .snapshot .rateMean
246
- m .lock .RUnlock ()
247
- return rateMean
233
+ defer m .lock .RUnlock ()
234
+ return m .snapshot .rateMean
248
235
}
249
236
250
237
// Snapshot returns a read-only copy of the meter.
@@ -264,9 +251,19 @@ func (m *StandardMeter) updateSnapshot() {
264
251
snapshot .rateMean = float64 (snapshot .count ) / time .Since (m .startTime ).Seconds ()
265
252
}
266
253
254
+ func (m * StandardMeter ) updateMeter () {
255
+ // should only run with write lock held on m.lock
256
+ n := atomic .LoadInt64 (& m .snapshot .temp )
257
+ m .snapshot .count += n
258
+ m .a1 .Update (n )
259
+ m .a5 .Update (n )
260
+ m .a15 .Update (n )
261
+ }
262
+
267
263
func (m * StandardMeter ) tick () {
268
264
m .lock .Lock ()
269
265
defer m .lock .Unlock ()
266
+ m .updateMeter ()
270
267
m .a1 .Tick ()
271
268
m .a5 .Tick ()
272
269
m .a15 .Tick ()
@@ -282,7 +279,7 @@ type meterArbiter struct {
282
279
ticker * time.Ticker
283
280
}
284
281
285
- var arbiter = meterArbiter {ticker : time .NewTicker (5e9 ), meters : make (map [* StandardMeter ]struct {})}
282
+ var arbiter = meterArbiter {ticker : time .NewTicker (5 * time . Second ), meters : make (map [* StandardMeter ]struct {})}
286
283
287
284
// Ticks meters on the scheduled interval
288
285
func (ma * meterArbiter ) tick () {
0 commit comments