From 9e07bb40ee66387252443b177a58aa366e8b42bc Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Fri, 25 Oct 2024 19:42:42 +0000 Subject: [PATCH 01/11] fix: stop activity bump if no tracked sessions --- coderd/workspacestats/reporter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coderd/workspacestats/reporter.go b/coderd/workspacestats/reporter.go index 6bb1b2dea4028..20e3cf7160e2c 100644 --- a/coderd/workspacestats/reporter.go +++ b/coderd/workspacestats/reporter.go @@ -136,8 +136,8 @@ func (r *Reporter) ReportAgentStats(ctx context.Context, now time.Time, workspac }, stats.Metrics) } - // if no active connections we do not bump activity - if stats.ConnectionCount == 0 { + // if no active sessions we do not bump activity + if stats.SessionCountJetbrains == 0 && stats.SessionCountVscode == 0 && stats.SessionCountReconnectingPty == 0 && stats.SessionCountSsh == 0 { return nil } From d702dca0279497413391a774dad5f1f16c72663b Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Fri, 25 Oct 2024 19:52:57 +0000 Subject: [PATCH 02/11] fix: do not bump activity with no sessions --- coderd/agentapi/stats_test.go | 38 ++--------------------------------- 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/coderd/agentapi/stats_test.go b/coderd/agentapi/stats_test.go index 83edb8cccc4e1..b3676d1f192ba 100644 --- a/coderd/agentapi/stats_test.go +++ b/coderd/agentapi/stats_test.go @@ -325,6 +325,7 @@ func TestUpdateStates(t *testing.T) { "dean": 2, }, ConnectionCount: 3, + SessionCountSsh: 3, }, } ) @@ -409,11 +410,7 @@ func TestUpdateStates(t *testing.T) { } batcher = &workspacestatstest.StatsBatcher{} updateAgentMetricsFnCalled = false - tickCh = make(chan time.Time) - flushCh = make(chan int, 1) - wut = workspacestats.NewTracker(dbM, - workspacestats.TrackerWithTickFlush(tickCh, flushCh), - ) + wut = workspacestats.NewTracker(dbM) req = &agentproto.UpdateStatsRequest{ Stats: &agentproto.Stats{ @@ -479,39 +476,15 @@ func TestUpdateStates(t *testing.T) { // Workspace gets fetched. dbM.EXPECT().GetWorkspaceByAgentID(gomock.Any(), agent.ID).Return(workspace, nil) - // We expect an activity bump because ConnectionCount > 0. - dbM.EXPECT().ActivityBumpWorkspace(gomock.Any(), database.ActivityBumpWorkspaceParams{ - WorkspaceID: workspace.ID, - NextAutostart: time.Time{}.UTC(), - }).Return(nil) - - // Workspace last used at gets bumped. - dbM.EXPECT().BatchUpdateWorkspaceLastUsedAt(gomock.Any(), database.BatchUpdateWorkspaceLastUsedAtParams{ - IDs: []uuid.UUID{workspace.ID}, - LastUsedAt: now, - }).Return(nil) - // User gets fetched to hit the UpdateAgentMetricsFn. dbM.EXPECT().GetUserByID(gomock.Any(), user.ID).Return(user, nil) - // Ensure that pubsub notifications are sent. - notifyDescription := make(chan []byte) - ps.Subscribe(codersdk.WorkspaceNotifyChannel(workspace.ID), func(_ context.Context, description []byte) { - go func() { - notifyDescription <- description - }() - }) - resp, err := api.UpdateStats(context.Background(), req) require.NoError(t, err) require.Equal(t, &agentproto.UpdateStatsResponse{ ReportInterval: durationpb.New(10 * time.Second), }, resp) - tickCh <- now - count := <-flushCh - require.Equal(t, 1, count, "expected one flush with one id") - batcher.Mu.Lock() defer batcher.Mu.Unlock() require.EqualValues(t, 1, batcher.Called) @@ -519,13 +492,6 @@ func TestUpdateStates(t *testing.T) { require.EqualValues(t, 0, batcher.LastStats.SessionCountJetbrains) require.EqualValues(t, 0, batcher.LastStats.SessionCountVscode) require.EqualValues(t, 0, batcher.LastStats.SessionCountReconnectingPty) - ctx := testutil.Context(t, testutil.WaitShort) - select { - case <-ctx.Done(): - t.Error("timed out while waiting for pubsub notification") - case description := <-notifyDescription: - require.Equal(t, description, []byte{}) - } require.True(t, updateAgentMetricsFnCalled) }) } From 218f4b0c28bdc0646b85b74634d67e4d2c329f1a Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Mon, 28 Oct 2024 16:07:56 +0000 Subject: [PATCH 03/11] fix test --- agent/agent.go | 6 ++++++ agent/agentssh/agentssh.go | 34 ++++++++++++++++++++++++++++---- agent/agentssh/jetbrainstrack.go | 5 ++++- coderd/activitybump_test.go | 6 ++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index cb0037dd0ed48..014a1efcef388 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -1503,6 +1503,12 @@ func (a *agent) Collect(ctx context.Context, networkStats map[netlogtype.Connect stats.SessionCountReconnectingPty = a.connCountReconnectingPTY.Load() + // if we've seen sessions but currently have no connections we + // just count the sum of the sessions as connections + if stats.ConnectionCount == 0 { + stats.ConnectionCount = stats.SessionCountSsh + stats.SessionCountVscode + stats.SessionCountJetbrains + stats.SessionCountReconnectingPty + } + // Compute the median connection latency! a.logger.Debug(ctx, "starting peer latency measurement for stats") var wg sync.WaitGroup diff --git a/agent/agentssh/agentssh.go b/agent/agentssh/agentssh.go index 081056b4f4ebd..d157092bcfe19 100644 --- a/agent/agentssh/agentssh.go +++ b/agent/agentssh/agentssh.go @@ -105,6 +105,9 @@ type Server struct { connCountVSCode atomic.Int64 connCountJetBrains atomic.Int64 connCountSSHSession atomic.Int64 + seenVSCode atomic.Bool + seenJetBrains atomic.Bool + seenSSHSession atomic.Bool metrics *sshServerMetrics } @@ -167,7 +170,7 @@ func NewServer(ctx context.Context, logger slog.Logger, prometheusRegistry *prom ChannelHandlers: map[string]ssh.ChannelHandler{ "direct-tcpip": func(srv *ssh.Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx ssh.Context) { // Wrapper is designed to find and track JetBrains Gateway connections. - wrapped := NewJetbrainsChannelWatcher(ctx, s.logger, newChan, &s.connCountJetBrains) + wrapped := NewJetbrainsChannelWatcher(ctx, s.logger, newChan, &s.connCountJetBrains, &s.seenJetBrains) ssh.DirectTCPIPHandler(srv, conn, wrapped, ctx) }, "direct-streamlocal@openssh.com": directStreamLocalHandler, @@ -245,10 +248,31 @@ type ConnStats struct { } func (s *Server) ConnStats() ConnStats { + // if we have 0 active connections, but we have seen a connection + // since the last time we collected, count it as 1 so that workspace + // activity is properly counted. + sshCount := s.connCountSSHSession.Load() + if sshCount == 0 && s.seenSSHSession.Load() { + sshCount = 1 + } + vscode := s.connCountVSCode.Load() + if vscode == 0 && s.seenVSCode.Load() { + vscode = 1 + } + jetbrains := s.connCountJetBrains.Load() + if jetbrains == 0 && s.seenJetBrains.Load() { + jetbrains = 1 + } + + // Reset the seen trackers for the next collection. + s.seenSSHSession.Store(false) + s.seenVSCode.Store(false) + s.seenJetBrains.Store(false) + return ConnStats{ - Sessions: s.connCountSSHSession.Load(), - VSCode: s.connCountVSCode.Load(), - JetBrains: s.connCountJetBrains.Load(), + Sessions: sshCount, + VSCode: vscode, + JetBrains: jetbrains, } } @@ -392,12 +416,14 @@ func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, extraEnv switch magicType { case MagicSessionTypeVSCode: s.connCountVSCode.Add(1) + s.seenVSCode.Store(true) defer s.connCountVSCode.Add(-1) case MagicSessionTypeJetBrains: // Do nothing here because JetBrains launches hundreds of ssh sessions. // We instead track JetBrains in the single persistent tcp forwarding channel. case "": s.connCountSSHSession.Add(1) + s.seenSSHSession.Store(true) defer s.connCountSSHSession.Add(-1) default: logger.Warn(ctx, "invalid magic ssh session type specified", slog.F("type", magicType)) diff --git a/agent/agentssh/jetbrainstrack.go b/agent/agentssh/jetbrainstrack.go index 534f2899b11ae..880caccfdb3b2 100644 --- a/agent/agentssh/jetbrainstrack.go +++ b/agent/agentssh/jetbrainstrack.go @@ -27,10 +27,11 @@ type localForwardChannelData struct { type JetbrainsChannelWatcher struct { gossh.NewChannel jetbrainsCounter *atomic.Int64 + jetbrainsSeen *atomic.Bool logger slog.Logger } -func NewJetbrainsChannelWatcher(ctx ssh.Context, logger slog.Logger, newChannel gossh.NewChannel, counter *atomic.Int64) gossh.NewChannel { +func NewJetbrainsChannelWatcher(ctx ssh.Context, logger slog.Logger, newChannel gossh.NewChannel, counter *atomic.Int64, seen *atomic.Bool) gossh.NewChannel { d := localForwardChannelData{} if err := gossh.Unmarshal(newChannel.ExtraData(), &d); err != nil { // If the data fails to unmarshal, do nothing. @@ -60,6 +61,7 @@ func NewJetbrainsChannelWatcher(ctx ssh.Context, logger slog.Logger, newChannel return &JetbrainsChannelWatcher{ NewChannel: newChannel, jetbrainsCounter: counter, + jetbrainsSeen: seen, logger: logger.With(slog.F("destination_port", d.DestPort)), } } @@ -70,6 +72,7 @@ func (w *JetbrainsChannelWatcher) Accept() (gossh.Channel, <-chan *gossh.Request return c, r, err } w.jetbrainsCounter.Add(1) + w.jetbrainsSeen.Store(true) // nolint: gocritic // JetBrains is a proper noun and should be capitalized w.logger.Debug(context.Background(), "JetBrains watcher accepted channel") diff --git a/coderd/activitybump_test.go b/coderd/activitybump_test.go index 60aec23475885..0ec813c0edcf3 100644 --- a/coderd/activitybump_test.go +++ b/coderd/activitybump_test.go @@ -212,6 +212,12 @@ func TestWorkspaceActivityBump(t *testing.T) { time.Sleep(time.Second * 3) sshConn, err := conn.SSHClient(ctx) require.NoError(t, err) + sess, err := sshConn.NewSession() + require.NoError(t, err) + err = sess.Shell() + require.NoError(t, err) + err = sess.Close() + require.NoError(t, err) _ = sshConn.Close() assertBumped(true) From 56cfa17986ae8839f10bc74dc719e0997dd2c625 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Mon, 28 Oct 2024 16:16:32 +0000 Subject: [PATCH 04/11] fix --- coderd/activitybump_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/coderd/activitybump_test.go b/coderd/activitybump_test.go index 0ec813c0edcf3..85b5709f2de26 100644 --- a/coderd/activitybump_test.go +++ b/coderd/activitybump_test.go @@ -256,6 +256,12 @@ func TestWorkspaceActivityBump(t *testing.T) { time.Sleep(time.Second * 3) sshConn, err := conn.SSHClient(ctx) require.NoError(t, err) + sess, err := sshConn.NewSession() + require.NoError(t, err) + err = sess.Shell() + require.NoError(t, err) + err = sess.Close() + require.NoError(t, err) _ = sshConn.Close() assertBumped(true) From d451924bed04e23c94e165057c67fbfd877d0422 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Mon, 28 Oct 2024 16:32:18 +0000 Subject: [PATCH 05/11] Revert "fix" This reverts commit 56cfa17986ae8839f10bc74dc719e0997dd2c625. --- coderd/activitybump_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/coderd/activitybump_test.go b/coderd/activitybump_test.go index 85b5709f2de26..0ec813c0edcf3 100644 --- a/coderd/activitybump_test.go +++ b/coderd/activitybump_test.go @@ -256,12 +256,6 @@ func TestWorkspaceActivityBump(t *testing.T) { time.Sleep(time.Second * 3) sshConn, err := conn.SSHClient(ctx) require.NoError(t, err) - sess, err := sshConn.NewSession() - require.NoError(t, err) - err = sess.Shell() - require.NoError(t, err) - err = sess.Close() - require.NoError(t, err) _ = sshConn.Close() assertBumped(true) From c0c0af53f78a27876735f4e6a9e9c552dcf4159e Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Mon, 28 Oct 2024 16:32:36 +0000 Subject: [PATCH 06/11] Revert "fix test" This reverts commit 218f4b0c28bdc0646b85b74634d67e4d2c329f1a. --- agent/agent.go | 6 ------ agent/agentssh/agentssh.go | 34 ++++---------------------------- agent/agentssh/jetbrainstrack.go | 5 +---- coderd/activitybump_test.go | 6 ------ 4 files changed, 5 insertions(+), 46 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index 014a1efcef388..cb0037dd0ed48 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -1503,12 +1503,6 @@ func (a *agent) Collect(ctx context.Context, networkStats map[netlogtype.Connect stats.SessionCountReconnectingPty = a.connCountReconnectingPTY.Load() - // if we've seen sessions but currently have no connections we - // just count the sum of the sessions as connections - if stats.ConnectionCount == 0 { - stats.ConnectionCount = stats.SessionCountSsh + stats.SessionCountVscode + stats.SessionCountJetbrains + stats.SessionCountReconnectingPty - } - // Compute the median connection latency! a.logger.Debug(ctx, "starting peer latency measurement for stats") var wg sync.WaitGroup diff --git a/agent/agentssh/agentssh.go b/agent/agentssh/agentssh.go index d157092bcfe19..081056b4f4ebd 100644 --- a/agent/agentssh/agentssh.go +++ b/agent/agentssh/agentssh.go @@ -105,9 +105,6 @@ type Server struct { connCountVSCode atomic.Int64 connCountJetBrains atomic.Int64 connCountSSHSession atomic.Int64 - seenVSCode atomic.Bool - seenJetBrains atomic.Bool - seenSSHSession atomic.Bool metrics *sshServerMetrics } @@ -170,7 +167,7 @@ func NewServer(ctx context.Context, logger slog.Logger, prometheusRegistry *prom ChannelHandlers: map[string]ssh.ChannelHandler{ "direct-tcpip": func(srv *ssh.Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx ssh.Context) { // Wrapper is designed to find and track JetBrains Gateway connections. - wrapped := NewJetbrainsChannelWatcher(ctx, s.logger, newChan, &s.connCountJetBrains, &s.seenJetBrains) + wrapped := NewJetbrainsChannelWatcher(ctx, s.logger, newChan, &s.connCountJetBrains) ssh.DirectTCPIPHandler(srv, conn, wrapped, ctx) }, "direct-streamlocal@openssh.com": directStreamLocalHandler, @@ -248,31 +245,10 @@ type ConnStats struct { } func (s *Server) ConnStats() ConnStats { - // if we have 0 active connections, but we have seen a connection - // since the last time we collected, count it as 1 so that workspace - // activity is properly counted. - sshCount := s.connCountSSHSession.Load() - if sshCount == 0 && s.seenSSHSession.Load() { - sshCount = 1 - } - vscode := s.connCountVSCode.Load() - if vscode == 0 && s.seenVSCode.Load() { - vscode = 1 - } - jetbrains := s.connCountJetBrains.Load() - if jetbrains == 0 && s.seenJetBrains.Load() { - jetbrains = 1 - } - - // Reset the seen trackers for the next collection. - s.seenSSHSession.Store(false) - s.seenVSCode.Store(false) - s.seenJetBrains.Store(false) - return ConnStats{ - Sessions: sshCount, - VSCode: vscode, - JetBrains: jetbrains, + Sessions: s.connCountSSHSession.Load(), + VSCode: s.connCountVSCode.Load(), + JetBrains: s.connCountJetBrains.Load(), } } @@ -416,14 +392,12 @@ func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, extraEnv switch magicType { case MagicSessionTypeVSCode: s.connCountVSCode.Add(1) - s.seenVSCode.Store(true) defer s.connCountVSCode.Add(-1) case MagicSessionTypeJetBrains: // Do nothing here because JetBrains launches hundreds of ssh sessions. // We instead track JetBrains in the single persistent tcp forwarding channel. case "": s.connCountSSHSession.Add(1) - s.seenSSHSession.Store(true) defer s.connCountSSHSession.Add(-1) default: logger.Warn(ctx, "invalid magic ssh session type specified", slog.F("type", magicType)) diff --git a/agent/agentssh/jetbrainstrack.go b/agent/agentssh/jetbrainstrack.go index 880caccfdb3b2..534f2899b11ae 100644 --- a/agent/agentssh/jetbrainstrack.go +++ b/agent/agentssh/jetbrainstrack.go @@ -27,11 +27,10 @@ type localForwardChannelData struct { type JetbrainsChannelWatcher struct { gossh.NewChannel jetbrainsCounter *atomic.Int64 - jetbrainsSeen *atomic.Bool logger slog.Logger } -func NewJetbrainsChannelWatcher(ctx ssh.Context, logger slog.Logger, newChannel gossh.NewChannel, counter *atomic.Int64, seen *atomic.Bool) gossh.NewChannel { +func NewJetbrainsChannelWatcher(ctx ssh.Context, logger slog.Logger, newChannel gossh.NewChannel, counter *atomic.Int64) gossh.NewChannel { d := localForwardChannelData{} if err := gossh.Unmarshal(newChannel.ExtraData(), &d); err != nil { // If the data fails to unmarshal, do nothing. @@ -61,7 +60,6 @@ func NewJetbrainsChannelWatcher(ctx ssh.Context, logger slog.Logger, newChannel return &JetbrainsChannelWatcher{ NewChannel: newChannel, jetbrainsCounter: counter, - jetbrainsSeen: seen, logger: logger.With(slog.F("destination_port", d.DestPort)), } } @@ -72,7 +70,6 @@ func (w *JetbrainsChannelWatcher) Accept() (gossh.Channel, <-chan *gossh.Request return c, r, err } w.jetbrainsCounter.Add(1) - w.jetbrainsSeen.Store(true) // nolint: gocritic // JetBrains is a proper noun and should be capitalized w.logger.Debug(context.Background(), "JetBrains watcher accepted channel") diff --git a/coderd/activitybump_test.go b/coderd/activitybump_test.go index 0ec813c0edcf3..60aec23475885 100644 --- a/coderd/activitybump_test.go +++ b/coderd/activitybump_test.go @@ -212,12 +212,6 @@ func TestWorkspaceActivityBump(t *testing.T) { time.Sleep(time.Second * 3) sshConn, err := conn.SSHClient(ctx) require.NoError(t, err) - sess, err := sshConn.NewSession() - require.NoError(t, err) - err = sess.Shell() - require.NoError(t, err) - err = sess.Close() - require.NoError(t, err) _ = sshConn.Close() assertBumped(true) From be0bbb4bb02cfb9c93fb58fc4cf743466dcc8152 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Mon, 28 Oct 2024 16:32:47 +0000 Subject: [PATCH 07/11] Revert "fix: do not bump activity with no sessions" This reverts commit d702dca0279497413391a774dad5f1f16c72663b. --- coderd/agentapi/stats_test.go | 38 +++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/coderd/agentapi/stats_test.go b/coderd/agentapi/stats_test.go index b3676d1f192ba..83edb8cccc4e1 100644 --- a/coderd/agentapi/stats_test.go +++ b/coderd/agentapi/stats_test.go @@ -325,7 +325,6 @@ func TestUpdateStates(t *testing.T) { "dean": 2, }, ConnectionCount: 3, - SessionCountSsh: 3, }, } ) @@ -410,7 +409,11 @@ func TestUpdateStates(t *testing.T) { } batcher = &workspacestatstest.StatsBatcher{} updateAgentMetricsFnCalled = false - wut = workspacestats.NewTracker(dbM) + tickCh = make(chan time.Time) + flushCh = make(chan int, 1) + wut = workspacestats.NewTracker(dbM, + workspacestats.TrackerWithTickFlush(tickCh, flushCh), + ) req = &agentproto.UpdateStatsRequest{ Stats: &agentproto.Stats{ @@ -476,15 +479,39 @@ func TestUpdateStates(t *testing.T) { // Workspace gets fetched. dbM.EXPECT().GetWorkspaceByAgentID(gomock.Any(), agent.ID).Return(workspace, nil) + // We expect an activity bump because ConnectionCount > 0. + dbM.EXPECT().ActivityBumpWorkspace(gomock.Any(), database.ActivityBumpWorkspaceParams{ + WorkspaceID: workspace.ID, + NextAutostart: time.Time{}.UTC(), + }).Return(nil) + + // Workspace last used at gets bumped. + dbM.EXPECT().BatchUpdateWorkspaceLastUsedAt(gomock.Any(), database.BatchUpdateWorkspaceLastUsedAtParams{ + IDs: []uuid.UUID{workspace.ID}, + LastUsedAt: now, + }).Return(nil) + // User gets fetched to hit the UpdateAgentMetricsFn. dbM.EXPECT().GetUserByID(gomock.Any(), user.ID).Return(user, nil) + // Ensure that pubsub notifications are sent. + notifyDescription := make(chan []byte) + ps.Subscribe(codersdk.WorkspaceNotifyChannel(workspace.ID), func(_ context.Context, description []byte) { + go func() { + notifyDescription <- description + }() + }) + resp, err := api.UpdateStats(context.Background(), req) require.NoError(t, err) require.Equal(t, &agentproto.UpdateStatsResponse{ ReportInterval: durationpb.New(10 * time.Second), }, resp) + tickCh <- now + count := <-flushCh + require.Equal(t, 1, count, "expected one flush with one id") + batcher.Mu.Lock() defer batcher.Mu.Unlock() require.EqualValues(t, 1, batcher.Called) @@ -492,6 +519,13 @@ func TestUpdateStates(t *testing.T) { require.EqualValues(t, 0, batcher.LastStats.SessionCountJetbrains) require.EqualValues(t, 0, batcher.LastStats.SessionCountVscode) require.EqualValues(t, 0, batcher.LastStats.SessionCountReconnectingPty) + ctx := testutil.Context(t, testutil.WaitShort) + select { + case <-ctx.Done(): + t.Error("timed out while waiting for pubsub notification") + case description := <-notifyDescription: + require.Equal(t, description, []byte{}) + } require.True(t, updateAgentMetricsFnCalled) }) } From 5a50fc37baf41da40f87de7a3fd42d4977b6c336 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Mon, 28 Oct 2024 16:33:02 +0000 Subject: [PATCH 08/11] Revert "fix: stop activity bump if no tracked sessions" This reverts commit 9e07bb40ee66387252443b177a58aa366e8b42bc. --- coderd/workspacestats/reporter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coderd/workspacestats/reporter.go b/coderd/workspacestats/reporter.go index 20e3cf7160e2c..6bb1b2dea4028 100644 --- a/coderd/workspacestats/reporter.go +++ b/coderd/workspacestats/reporter.go @@ -136,8 +136,8 @@ func (r *Reporter) ReportAgentStats(ctx context.Context, now time.Time, workspac }, stats.Metrics) } - // if no active sessions we do not bump activity - if stats.SessionCountJetbrains == 0 && stats.SessionCountVscode == 0 && stats.SessionCountReconnectingPty == 0 && stats.SessionCountSsh == 0 { + // if no active connections we do not bump activity + if stats.ConnectionCount == 0 { return nil } From 4f0e506f3ac2978b6cd47cc4279fb7c2e9e1d599 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Mon, 28 Oct 2024 16:37:51 +0000 Subject: [PATCH 09/11] new way --- coderd/workspacestats/reporter.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/coderd/workspacestats/reporter.go b/coderd/workspacestats/reporter.go index 6bb1b2dea4028..36aea4464e08a 100644 --- a/coderd/workspacestats/reporter.go +++ b/coderd/workspacestats/reporter.go @@ -136,8 +136,13 @@ func (r *Reporter) ReportAgentStats(ctx context.Context, now time.Time, workspac }, stats.Metrics) } - // if no active connections we do not bump activity - if stats.ConnectionCount == 0 { + // workspace activity: if no sessions we do not bump activity + if usage && stats.SessionCountVscode == 0 && stats.SessionCountJetbrains == 0 && stats.SessionCountReconnectingPty == 0 && stats.SessionCountSsh == 0 { + return nil + } + + // legacy stats: if no active connections we do not bump activity + if !usage && stats.ConnectionCount == 0 { return nil } From 599d71f164f35cce8ed5987217d0709f0e1055c8 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Mon, 28 Oct 2024 16:44:11 +0000 Subject: [PATCH 10/11] lint --- coderd/workspacestats/reporter.go | 1 + 1 file changed, 1 insertion(+) diff --git a/coderd/workspacestats/reporter.go b/coderd/workspacestats/reporter.go index 36aea4464e08a..a2812eba2d8b3 100644 --- a/coderd/workspacestats/reporter.go +++ b/coderd/workspacestats/reporter.go @@ -117,6 +117,7 @@ func (r *Reporter) ReportAppStats(ctx context.Context, stats []workspaceapps.Sta return nil } +//nolint:revive usage is a control flag while we have the experiment func (r *Reporter) ReportAgentStats(ctx context.Context, now time.Time, workspace database.Workspace, workspaceAgent database.WorkspaceAgent, templateName string, stats *agentproto.Stats, usage bool) error { // update agent stats r.opts.StatsBatcher.Add(now, workspaceAgent.ID, workspace.TemplateID, workspace.OwnerID, workspace.ID, stats, usage) From 79af2ba89f24a0b29a9f1db106bde10bdf06c279 Mon Sep 17 00:00:00 2001 From: Garrett Delfosse Date: Tue, 29 Oct 2024 17:54:48 +0000 Subject: [PATCH 11/11] lint --- coderd/workspacestats/reporter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/workspacestats/reporter.go b/coderd/workspacestats/reporter.go index a2812eba2d8b3..e59a9f15d5e95 100644 --- a/coderd/workspacestats/reporter.go +++ b/coderd/workspacestats/reporter.go @@ -117,7 +117,7 @@ func (r *Reporter) ReportAppStats(ctx context.Context, stats []workspaceapps.Sta return nil } -//nolint:revive usage is a control flag while we have the experiment +// nolint:revive // usage is a control flag while we have the experiment func (r *Reporter) ReportAgentStats(ctx context.Context, now time.Time, workspace database.Workspace, workspaceAgent database.WorkspaceAgent, templateName string, stats *agentproto.Stats, usage bool) error { // update agent stats r.opts.StatsBatcher.Add(now, workspaceAgent.ID, workspace.TemplateID, workspace.OwnerID, workspace.ID, stats, usage) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy