diff --git a/meter.go b/meter.go index 0389ab0..9adce5a 100644 --- a/meter.go +++ b/meter.go @@ -190,10 +190,13 @@ func (m *StandardMeter) Snapshot() Meter { func (m *StandardMeter) updateSnapshot() { // should run with write lock held on m.lock snapshot := m.snapshot - snapshot.rate1 = m.a1.Rate() - snapshot.rate5 = m.a5.Rate() - snapshot.rate15 = m.a15.Rate() - snapshot.rateMean = float64(snapshot.count) / time.Since(m.startTime).Seconds() + elapsed := time.Since(m.startTime).Seconds() + if elapsed >= 0 { + snapshot.rate1 = m.a1.Rate() + snapshot.rate5 = m.a5.Rate() + snapshot.rate15 = m.a15.Rate() + snapshot.rateMean = float64(snapshot.count) / elapsed + } } func (m *StandardMeter) tick() { diff --git a/timer.go b/timer.go index 17db8f8..3eb1225 100644 --- a/timer.go +++ b/timer.go @@ -215,18 +215,18 @@ func (t *StandardTimer) Time(f func()) { // Record the duration of an event. func (t *StandardTimer) Update(d time.Duration) { - t.mutex.Lock() - defer t.mutex.Unlock() - t.histogram.Update(int64(d)) - t.meter.Mark(1) + // Partial workaround for detecting a clock change + if d >= 0 { + t.mutex.Lock() + defer t.mutex.Unlock() + t.histogram.Update(int64(d)) + t.meter.Mark(1) + } } // Record the duration of an event that started at a time and ends now. func (t *StandardTimer) UpdateSince(ts time.Time) { - t.mutex.Lock() - defer t.mutex.Unlock() - t.histogram.Update(int64(time.Since(ts))) - t.meter.Mark(1) + t.Update(time.Since(ts)) } // Variance returns the variance of the values in the sample. diff --git a/timer_test.go b/timer_test.go index 313d691..f908da3 100644 --- a/timer_test.go +++ b/timer_test.go @@ -27,6 +27,7 @@ func TestTimerExtremes(t *testing.T) { tm := NewTimer() tm.Update(math.MaxInt64) tm.Update(0) + tm.Update(math.MinInt64) if stdDev := tm.StdDev(); 4.611686018427388e+18 != stdDev { t.Errorf("tm.StdDev(): 4.611686018427388e+18 != %v\n", stdDev) }