|
6 | 6 | "time"
|
7 | 7 |
|
8 | 8 | "github.com/google/uuid"
|
9 |
| - "golang.org/x/sync/errgroup" |
10 | 9 | "golang.org/x/xerrors"
|
11 | 10 |
|
12 | 11 | "cdr.dev/slog"
|
@@ -119,69 +118,58 @@ func (r *Reporter) ReportAppStats(ctx context.Context, stats []workspaceapps.Sta
|
119 | 118 | }
|
120 | 119 |
|
121 | 120 | func (r *Reporter) ReportAgentStats(ctx context.Context, now time.Time, workspace database.Workspace, workspaceAgent database.WorkspaceAgent, templateName string, stats *agentproto.Stats, usage bool) error {
|
122 |
| - if stats.ConnectionCount > 0 { |
123 |
| - var nextAutostart time.Time |
124 |
| - if workspace.AutostartSchedule.String != "" { |
125 |
| - templateSchedule, err := (*(r.opts.TemplateScheduleStore.Load())).Get(ctx, r.opts.Database, workspace.TemplateID) |
126 |
| - // If the template schedule fails to load, just default to bumping |
127 |
| - // without the next transition and log it. |
128 |
| - if err != nil { |
129 |
| - r.opts.Logger.Error(ctx, "failed to load template schedule bumping activity, defaulting to bumping by 60min", |
130 |
| - slog.F("workspace_id", workspace.ID), |
131 |
| - slog.F("template_id", workspace.TemplateID), |
132 |
| - slog.Error(err), |
133 |
| - ) |
134 |
| - } else { |
135 |
| - next, allowed := schedule.NextAutostart(now, workspace.AutostartSchedule.String, templateSchedule) |
136 |
| - if allowed { |
137 |
| - nextAutostart = next |
138 |
| - } |
139 |
| - } |
140 |
| - } |
141 |
| - ActivityBumpWorkspace(ctx, r.opts.Logger.Named("activity_bump"), r.opts.Database, workspace.ID, nextAutostart) |
142 |
| - } |
| 121 | + // update agent stats |
| 122 | + r.opts.StatsBatcher.Add(now, workspaceAgent.ID, workspace.TemplateID, workspace.OwnerID, workspace.ID, stats, usage) |
143 | 123 |
|
144 |
| - var errGroup errgroup.Group |
145 |
| - errGroup.Go(func() error { |
146 |
| - err := r.opts.StatsBatcher.Add(now, workspaceAgent.ID, workspace.TemplateID, workspace.OwnerID, workspace.ID, stats, usage) |
147 |
| - if err != nil { |
148 |
| - r.opts.Logger.Error(ctx, "add agent stats to batcher", slog.Error(err)) |
149 |
| - return xerrors.Errorf("insert workspace agent stats batch: %w", err) |
150 |
| - } |
151 |
| - return nil |
152 |
| - }) |
153 |
| - errGroup.Go(func() error { |
154 |
| - err := r.opts.Database.UpdateWorkspaceLastUsedAt(ctx, database.UpdateWorkspaceLastUsedAtParams{ |
155 |
| - ID: workspace.ID, |
156 |
| - LastUsedAt: now, |
157 |
| - }) |
| 124 | + // update prometheus metrics |
| 125 | + if r.opts.UpdateAgentMetricsFn != nil { |
| 126 | + user, err := r.opts.Database.GetUserByID(ctx, workspace.OwnerID) |
158 | 127 | if err != nil {
|
159 |
| - return xerrors.Errorf("update workspace LastUsedAt: %w", err) |
| 128 | + return xerrors.Errorf("get user: %w", err) |
160 | 129 | }
|
| 130 | + |
| 131 | + r.opts.UpdateAgentMetricsFn(ctx, prometheusmetrics.AgentMetricLabels{ |
| 132 | + Username: user.Username, |
| 133 | + WorkspaceName: workspace.Name, |
| 134 | + AgentName: workspaceAgent.Name, |
| 135 | + TemplateName: templateName, |
| 136 | + }, stats.Metrics) |
161 | 137 | return nil
|
162 |
| - }) |
163 |
| - if r.opts.UpdateAgentMetricsFn != nil { |
164 |
| - errGroup.Go(func() error { |
165 |
| - user, err := r.opts.Database.GetUserByID(ctx, workspace.OwnerID) |
166 |
| - if err != nil { |
167 |
| - return xerrors.Errorf("get user: %w", err) |
168 |
| - } |
| 138 | + } |
169 | 139 |
|
170 |
| - r.opts.UpdateAgentMetricsFn(ctx, prometheusmetrics.AgentMetricLabels{ |
171 |
| - Username: user.Username, |
172 |
| - WorkspaceName: workspace.Name, |
173 |
| - AgentName: workspaceAgent.Name, |
174 |
| - TemplateName: templateName, |
175 |
| - }, stats.Metrics) |
176 |
| - return nil |
177 |
| - }) |
| 140 | + // if no active sessions we do not bump activity |
| 141 | + if stats.SessionCountJetbrains == 0 && stats.SessionCountReconnectingPty == 0 && stats.SessionCountSsh == 0 && stats.SessionCountVscode == 0 { |
| 142 | + return nil |
178 | 143 | }
|
179 |
| - err := errGroup.Wait() |
180 |
| - if err != nil { |
181 |
| - return xerrors.Errorf("update stats in database: %w", err) |
| 144 | + |
| 145 | + // check next autostart |
| 146 | + var nextAutostart time.Time |
| 147 | + if workspace.AutostartSchedule.String != "" { |
| 148 | + templateSchedule, err := (*(r.opts.TemplateScheduleStore.Load())).Get(ctx, r.opts.Database, workspace.TemplateID) |
| 149 | + // If the template schedule fails to load, just default to bumping |
| 150 | + // without the next transition and log it. |
| 151 | + if err != nil { |
| 152 | + r.opts.Logger.Error(ctx, "failed to load template schedule bumping activity, defaulting to bumping by 60min", |
| 153 | + slog.F("workspace_id", workspace.ID), |
| 154 | + slog.F("template_id", workspace.TemplateID), |
| 155 | + slog.Error(err), |
| 156 | + ) |
| 157 | + } else { |
| 158 | + next, allowed := schedule.NextAutostart(now, workspace.AutostartSchedule.String, templateSchedule) |
| 159 | + if allowed { |
| 160 | + nextAutostart = next |
| 161 | + } |
| 162 | + } |
182 | 163 | }
|
183 | 164 |
|
184 |
| - err = r.opts.Pubsub.Publish(codersdk.WorkspaceNotifyChannel(workspace.ID), []byte{}) |
| 165 | + // bump workspace activity |
| 166 | + ActivityBumpWorkspace(ctx, r.opts.Logger.Named("activity_bump"), r.opts.Database, workspace.ID, nextAutostart) |
| 167 | + |
| 168 | + // bump workspace last_used_at |
| 169 | + r.opts.UsageTracker.Add(workspace.ID) |
| 170 | + |
| 171 | + // notify workspace update |
| 172 | + err := r.opts.Pubsub.Publish(codersdk.WorkspaceNotifyChannel(workspace.ID), []byte{}) |
185 | 173 | if err != nil {
|
186 | 174 | r.opts.Logger.Warn(ctx, "failed to publish workspace agent stats",
|
187 | 175 | slog.F("workspace_id", workspace.ID), slog.Error(err))
|
|
0 commit comments