Skip to content

Commit

Permalink
Partial workaround for timer during a clock jump
Browse files Browse the repository at this point in the history
`time.Now()` uses the wall-clock and therefore calling it twice, one
second apart, can produce quite different results (negative results but
also a difference greater than one second). Go doesn't expose a
monotonic clock, therefore, it's difficult to properly fix (but there is
https://github.com/gavv/monotime if we want a proper fix for
`timer.Time()`).

This workaround just discard any non-positive duration.
  • Loading branch information
vincentbernat committed Jan 2, 2017
1 parent 1f30fe9 commit 2e2529e
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 8 deletions.
16 changes: 8 additions & 8 deletions timer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions timer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

0 comments on commit 2e2529e

Please sign in to comment.