Skip to content

Commit bbd34e1

Browse files
minor fixes
1 parent 3b697d0 commit bbd34e1

File tree

2 files changed

+52
-24
lines changed

2 files changed

+52
-24
lines changed

enterprise/coderd/prebuilds/metricscollector.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,7 @@ func (k hardLimitedPresetKey) String() string {
280280
return fmt.Sprintf("%s:%s:%s", k.orgName, k.templateName, k.presetName)
281281
}
282282

283-
// nolint:revive // isHardLimited determines if the preset should be reported as hard-limited in Prometheus.
284-
func (mc *MetricsCollector) trackHardLimitedStatus(isPresetHardLimited map[hardLimitedPresetKey]bool) {
283+
func (mc *MetricsCollector) registerHardLimitedPresets(isPresetHardLimited map[hardLimitedPresetKey]bool) {
285284
mc.isPresetHardLimitedMu.Lock()
286285
defer mc.isPresetHardLimitedMu.Unlock()
287286

enterprise/coderd/prebuilds/reconcile.go

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -257,28 +257,7 @@ func (c *StoreReconciler) ReconcileAll(ctx context.Context) error {
257257
return xerrors.Errorf("determine current snapshot: %w", err)
258258
}
259259

260-
presetsMap := make(map[hardLimitedPresetKey][]database.GetTemplatePresetsWithPrebuildsRow)
261-
for _, preset := range snapshot.Presets {
262-
key := hardLimitedPresetKey{
263-
orgName: preset.OrganizationName,
264-
templateName: preset.TemplateName,
265-
presetName: preset.Name,
266-
}
267-
268-
presetsMap[key] = append(presetsMap[key], preset)
269-
}
270-
271-
isPresetHardLimited := make(map[hardLimitedPresetKey]bool)
272-
for key, presets := range presetsMap {
273-
for _, preset := range presets {
274-
if preset.UsingActiveVersion && !preset.Deleted && snapshot.IsHardLimited(preset.ID) {
275-
isPresetHardLimited[key] = true
276-
break
277-
}
278-
}
279-
}
280-
281-
c.metrics.trackHardLimitedStatus(isPresetHardLimited)
260+
c.reportHardLimitedPresets(snapshot)
282261

283262
if len(snapshot.Presets) == 0 {
284263
logger.Debug(ctx, "no templates found with prebuilds configured")
@@ -320,6 +299,56 @@ func (c *StoreReconciler) ReconcileAll(ctx context.Context) error {
320299
return err
321300
}
322301

302+
// Report a metric only if the preset uses the latest version of the template and the template is not deleted.
303+
// This avoids conflicts between metrics from old and new template versions.
304+
//
305+
// NOTE: Multiple versions of a preset can exist with the same orgName, templateName, and presetName,
306+
// because templates can have multiple versions — or deleted templates can share the same name.
307+
//
308+
// The safest approach is to report the metric only for the latest version of the preset.
309+
// When a new template version is released, the metric for the new preset should overwrite
310+
// the old value in Prometheus.
311+
//
312+
// However, there’s one edge case: if an admin creates a template, it becomes hard-limited,
313+
// then deletes the template and never creates another with the same name,
314+
// the old preset will continue to be reported as hard-limited —
315+
// even though it’s deleted. This will persist until `coderd` is restarted.
316+
317+
func (c *StoreReconciler) reportHardLimitedPresets(snapshot *prebuilds.GlobalSnapshot) {
318+
// presetsMap is a map from key (orgName:templateName:presetName) to list of corresponding presets.
319+
// Multiple versions of a preset can exist with the same orgName, templateName, and presetName,
320+
// because templates can have multiple versions — or deleted templates can share the same name.
321+
presetsMap := make(map[hardLimitedPresetKey][]database.GetTemplatePresetsWithPrebuildsRow)
322+
for _, preset := range snapshot.Presets {
323+
key := hardLimitedPresetKey{
324+
orgName: preset.OrganizationName,
325+
templateName: preset.TemplateName,
326+
presetName: preset.Name,
327+
}
328+
329+
presetsMap[key] = append(presetsMap[key], preset)
330+
}
331+
332+
// Report a preset as hard-limited only if all the following conditions are met:
333+
// - The preset is marked as hard-limited
334+
// - The preset is using the active version of its template, and the template has not been deleted
335+
//
336+
// The second condition is important because a hard-limited preset that has become outdated is no longer relevant.
337+
// Its associated prebuilt workspaces were likely deleted, and it's not meaningful to continue reporting it
338+
// as hard-limited to the admin.
339+
isPresetHardLimited := make(map[hardLimitedPresetKey]bool)
340+
for key, presets := range presetsMap {
341+
for _, preset := range presets {
342+
if preset.UsingActiveVersion && !preset.Deleted && snapshot.IsHardLimited(preset.ID) {
343+
isPresetHardLimited[key] = true
344+
break
345+
}
346+
}
347+
}
348+
349+
c.metrics.registerHardLimitedPresets(isPresetHardLimited)
350+
}
351+
323352
// SnapshotState captures the current state of all prebuilds across templates.
324353
func (c *StoreReconciler) SnapshotState(ctx context.Context, store database.Store) (*prebuilds.GlobalSnapshot, error) {
325354
if err := ctx.Err(); err != nil {

0 commit comments

Comments
 (0)