From 904997d41e61150200fa54563e1502cd3c47561e Mon Sep 17 00:00:00 2001 From: Mike Kao Date: Thu, 14 Nov 2024 17:34:33 +0800 Subject: [PATCH] fix(RollingCounter): prevent 'now' from accumulating during cleanup --- memmetrics/counter.go | 6 +++--- memmetrics/counter_test.go | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/memmetrics/counter.go b/memmetrics/counter.go index cab92aac..5a7578a4 100644 --- a/memmetrics/counter.go +++ b/memmetrics/counter.go @@ -131,9 +131,9 @@ func (c *RollingCounter) getBucket(t time.Time) int { func (c *RollingCounter) cleanup() { now := clock.Now().UTC() for i := 0; i < len(c.values); i++ { - now = now.Add(time.Duration(-1*i) * c.resolution) - if now.Truncate(c.resolution).After(c.lastUpdated.Truncate(c.resolution)) { - c.values[c.getBucket(now)] = 0 + checkPoint := now.Add(time.Duration(-1*i) * c.resolution) + if checkPoint.Truncate(c.resolution).After(c.lastUpdated.Truncate(c.resolution)) { + c.values[c.getBucket(checkPoint)] = 0 } else { break } diff --git a/memmetrics/counter_test.go b/memmetrics/counter_test.go index c03b1f64..5218358e 100644 --- a/memmetrics/counter_test.go +++ b/memmetrics/counter_test.go @@ -27,3 +27,22 @@ func TestCloneExpired(t *testing.T) { assert.EqualValues(t, 2, out.Count()) } + +func TestCleanup(t *testing.T) { + clock.Freeze(clock.Date(2012, 3, 4, 5, 6, 7, 0, clock.UTC)) + + cnt, err := NewCounter(10, clock.Second) + require.NoError(t, err) + + cnt.Inc(1) + for i := 0; i < 9; i++ { + clock.Advance(clock.Second) + cnt.Inc(1) + } + // cnt will be [1 1 1 1 1 1 1 1 1 1] + + clock.Advance(9 * clock.Second) + assert.EqualValues(t, 1, cnt.Count()) + // cnt will be [0 0 0 0 0 0 1 0 0 0] + // old behavior [1 1 0 1 0 0 1 1 1 0] +}