@@ -18,7 +18,7 @@ import (
1818"github.com/coder/coder/v2/coderd/database/pubsub"
1919"github.com/coder/coder/v2/coderd/prometheusmetrics"
2020"github.com/coder/coder/v2/coderd/schedule"
21- "github.com/coder/coder/v2/codersdk "
21+ "github.com/coder/coder/v2/coderd/workspaceapps "
2222)
2323
2424type StatsBatcher interface {
@@ -34,6 +34,7 @@ type StatsAPI struct {
3434TemplateScheduleStore * atomic.Pointer [schedule.TemplateScheduleStore ]
3535AgentStatsRefreshInterval time.Duration
3636UpdateAgentMetricsFn func (ctx context.Context ,labels prometheusmetrics.AgentMetricLabels ,metrics []* agentproto.Stats_Metric )
37+ StatsCollector workspaceapps.StatsCollector
3738
3839TimeNowFn func () time.Time // defaults to dbtime.Now()
3940}
@@ -70,28 +71,6 @@ func (a *StatsAPI) UpdateStats(ctx context.Context, req *agentproto.UpdateStatsR
7071)
7172
7273now := a .now ()
73- // if req.Stats.ConnectionCount > 0 {
74- // var nextAutostart time.Time
75- // if workspace.AutostartSchedule.String != "" {
76- // templateSchedule, err := (*(a.TemplateScheduleStore.Load())).Get(ctx, a.Database, workspace.TemplateID)
77- // // If the template schedule fails to load, just default to bumping
78- // // without the next transition and log it.
79- // if err != nil {
80- // a.Log.Error(ctx, "failed to load template schedule bumping activity, defaulting to bumping by 60min",
81- // slog.F("workspace_id", workspace.ID),
82- // slog.F("template_id", workspace.TemplateID),
83- // slog.Error(err),
84- // )
85- // } else {
86- // next, allowed := schedule.NextAutostart(now, workspace.AutostartSchedule.String, templateSchedule)
87- // if allowed {
88- // nextAutostart = next
89- // }
90- // }
91- // }
92- // ActivityBumpWorkspace(ctx, a.Log.Named("activity_bump"), a.Database, workspace.ID, nextAutostart)
93- // }
94-
9574var errGroup errgroup.Group
9675errGroup .Go (func ()error {
9776err := a .StatsBatcher .Add (now ,workspaceAgent .ID ,workspace .TemplateID ,workspace .OwnerID ,workspace .ID ,req .Stats )
@@ -101,17 +80,6 @@ func (a *StatsAPI) UpdateStats(ctx context.Context, req *agentproto.UpdateStatsR
10180}
10281return nil
10382})
104- errGroup .Go (func ()error {
105- // nolint:gocritic // (#13146) Will be moved soon as part of refactor.
106- err := a .Database .UpdateWorkspaceLastUsedAt (ctx , database.UpdateWorkspaceLastUsedAtParams {
107- ID :workspace .ID ,
108- LastUsedAt :now ,
109- })
110- if err != nil {
111- return xerrors .Errorf ("update workspace LastUsedAt: %w" ,err )
112- }
113- return nil
114- })
11583if a .UpdateAgentMetricsFn != nil {
11684errGroup .Go (func ()error {
11785user ,err := a .Database .GetUserByID (ctx ,workspace .OwnerID )
@@ -133,16 +101,12 @@ func (a *StatsAPI) UpdateStats(ctx context.Context, req *agentproto.UpdateStatsR
133101return nil ,xerrors .Errorf ("update stats in database: %w" ,err )
134102}
135103
136- // Tell the frontend about the new agent report, now that everything is updated
137- a .publishWorkspaceAgentStats (ctx ,workspace .ID )
104+ // Flushing the stats collector will update last_used_at,
105+ // dealine for the workspace, and will publish a workspace update event.
106+ a .StatsCollector .CollectAndFlush (ctx , workspaceapps.StatsReport {
107+ WorkspaceID :workspace .ID ,
108+ // TODO: fill out
109+ })
138110
139111return res ,nil
140112}
141-
142- func (a * StatsAPI )publishWorkspaceAgentStats (ctx context.Context ,workspaceID uuid.UUID ) {
143- err := a .Pubsub .Publish (codersdk .WorkspaceNotifyChannel (workspaceID ), []byte {})
144- if err != nil {
145- a .Log .Warn (ctx ,"failed to publish workspace agent stats" ,
146- slog .F ("workspace_id" ,workspaceID ),slog .Error (err ))
147- }
148- }