From 806421153287f9ee87f3b8dcf59dd762ae4833bb Mon Sep 17 00:00:00 2001 From: Matt Schallert Date: Mon, 15 May 2017 11:59:43 -0400 Subject: [PATCH] Report buffered metrics one final time on Close() (#44) --- .travis.yml | 2 +- scope.go | 19 +++++++++++++++++-- scope_test.go | 17 ++++++++++++++++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 127fee99..485f9c9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ go: - 1.5 - 1.6 - 1.7 - - tip + - 1.8 env: global: - GO15VENDOREXPERIMENT=1 diff --git a/scope.go b/scope.go index ed648d29..834a8ef7 100644 --- a/scope.go +++ b/scope.go @@ -247,6 +247,13 @@ func (s *scope) reportLoopRun() { return } + s.reportRegistryWithLock() + + s.status.RUnlock() +} + +// reports current registry with scope status lock held +func (s *scope) reportRegistryWithLock() { s.registry.RLock() if s.reporter != nil { for _, ss := range s.registry.subscopes { @@ -258,8 +265,6 @@ func (s *scope) reportLoopRun() { } } s.registry.RUnlock() - - s.status.RUnlock() } func (s *scope) Counter(name string) Counter { @@ -479,8 +484,18 @@ func (s *scope) Snapshot() Snapshot { func (s *scope) Close() error { s.status.Lock() + + // don't wait to close more than once (panic on double close of + // s.status.quit) + if s.status.closed { + s.status.Unlock() + return nil + } + s.status.closed = true close(s.status.quit) + s.reportRegistryWithLock() + s.status.Unlock() if closer, ok := s.baseReporter.(io.Closer); ok { diff --git a/scope_test.go b/scope_test.go index 242737e8..9ac78108 100644 --- a/scope_test.go +++ b/scope_test.go @@ -693,5 +693,20 @@ func TestScopeAvoidReportLoopRunOnClose(t *testing.T) { assert.NoError(t, closer.Close()) s.reportLoopRun() - assert.Equal(t, int32(1), atomic.LoadInt32(&r.flushes)) + assert.Equal(t, int32(2), atomic.LoadInt32(&r.flushes)) +} + +func TestScopeFlushOnClose(t *testing.T) { + r := newTestStatsReporter() + root, closer := NewRootScope(ScopeOptions{Reporter: r}, time.Hour) + + r.cg.Add(1) + root.Counter("foo").Inc(1) + assert.Nil(t, r.counters["foo"]) + + assert.NoError(t, closer.Close()) + + assert.EqualValues(t, 1, r.counters["foo"].val) + + assert.NoError(t, closer.Close()) }