diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 86f2057..25aef45 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -60,17 +60,22 @@ func New() *Tracker { } } -// SetConnected updates the connection status +// SetConnected updates the connection status. Every connection after the +// first counts one reconnect. func (t *Tracker) SetConnected(connected bool) { - wasConnected := t.isConnected.Swap(connected) - if connected { - t.mu.Lock() - t.connectedSince = time.Now() - t.mu.Unlock() - // Increment reconnect count (but not for the initial connection) - if wasConnected || t.reconnectCount.Load() > 0 { - t.reconnectCount.Add(1) - } + t.isConnected.Store(connected) + if !connected { + return + } + + t.mu.Lock() + // connectedSince is zero until the first connection. + connectedBefore := !t.connectedSince.IsZero() + t.connectedSince = time.Now() + t.mu.Unlock() + + if connectedBefore { + t.reconnectCount.Add(1) } } diff --git a/internal/metrics/metrics_test.go b/internal/metrics/metrics_test.go new file mode 100644 index 0000000..e8776fd --- /dev/null +++ b/internal/metrics/metrics_test.go @@ -0,0 +1,21 @@ +package metrics + +import "testing" + +// TestReconnectCount connects three times with a disconnect between each, the +// way the streamer does, and expects every connection after the first to count +// one reconnect. +func TestReconnectCount(t *testing.T) { + tracker := New() + + tracker.SetConnected(true) + tracker.SetConnected(false) + tracker.SetConnected(true) + tracker.SetConnected(false) + tracker.SetConnected(true) + + const wantReconnects = 2 + if got := tracker.GetReconnectCount(); got != wantReconnects { + t.Fatalf("reconnect count = %d, want %d", got, wantReconnects) + } +}