Skip to content

Commit fcbfb7f

Browse files
committed
chore: improvements
Signed-off-by: Danny Kopping <dannykopping@gmail.com>
1 parent 562b56d commit fcbfb7f

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

enterprise/coderd/prebuilds/metricscollector.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package prebuilds
22

33
import (
44
"context"
5+
"fmt"
56
"sync/atomic"
67
"time"
78

@@ -11,7 +12,6 @@ import (
1112
"cdr.dev/slog"
1213

1314
"github.com/coder/coder/v2/coderd/database"
14-
"github.com/coder/coder/v2/coderd/database/dbauthz"
1515
"github.com/coder/coder/v2/coderd/prebuilds"
1616
)
1717

@@ -57,6 +57,12 @@ var (
5757
labels,
5858
nil,
5959
)
60+
lastUpdateDesc = prometheus.NewDesc(
61+
"coderd_prebuilt_workspaces_metrics_last_updated",
62+
"The unix timestamp when the metrics related to prebuilt workspaces were last updated; these metrics are cached.",
63+
[]string{},
64+
nil,
65+
)
6066
)
6167

6268
const (
@@ -74,7 +80,6 @@ type MetricsCollector struct {
7480

7581
var _ prometheus.Collector = new(MetricsCollector)
7682

77-
// NewMetricsCollector returns a
7883
func NewMetricsCollector(db database.Store, logger slog.Logger, snapshotter prebuilds.StateSnapshotter) *MetricsCollector {
7984
log := logger.Named("prebuilds_metrics_collector")
8085
return &MetricsCollector{
@@ -91,18 +96,16 @@ func (*MetricsCollector) Describe(descCh chan<- *prometheus.Desc) {
9196
descCh <- desiredPrebuildsDesc
9297
descCh <- runningPrebuildsDesc
9398
descCh <- eligiblePrebuildsDesc
99+
descCh <- lastUpdateDesc
94100
}
95101

96102
// Collect uses the cached state to set configured metrics.
97103
// The state is cached because this function can be called multiple times per second and retrieving the current state
98104
// is an expensive operation.
99105
func (mc *MetricsCollector) Collect(metricsCh chan<- prometheus.Metric) {
100-
// nolint:gocritic // We need to set an authz context to read metrics from the db.
101-
ctx := dbauthz.AsPrebuildsOrchestrator(context.Background())
102-
103-
currentState := mc.latestState.Load()
106+
currentState := mc.latestState.Load() // Grab a copy; it's ok if it goes stale during the course of this func.
104107
if currentState == nil {
105-
mc.logger.Warn(ctx, "failed to set prebuilds metrics; state not set")
108+
mc.logger.Warn(context.Background(), "failed to set prebuilds metrics; state not set")
106109
return
107110
}
108111

@@ -119,7 +122,7 @@ func (mc *MetricsCollector) Collect(metricsCh chan<- prometheus.Metric) {
119122

120123
presetSnapshot, err := currentState.snapshot.FilterByPreset(preset.ID)
121124
if err != nil {
122-
mc.logger.Error(ctx, "failed to filter by preset", slog.Error(err))
125+
mc.logger.Error(context.Background(), "failed to filter by preset", slog.Error(err))
123126
continue
124127
}
125128
state := presetSnapshot.CalculateState()
@@ -128,11 +131,14 @@ func (mc *MetricsCollector) Collect(metricsCh chan<- prometheus.Metric) {
128131
metricsCh <- prometheus.MustNewConstMetric(runningPrebuildsDesc, prometheus.GaugeValue, float64(state.Actual), preset.TemplateName, preset.Name, preset.OrganizationName)
129132
metricsCh <- prometheus.MustNewConstMetric(eligiblePrebuildsDesc, prometheus.GaugeValue, float64(state.Eligible), preset.TemplateName, preset.Name, preset.OrganizationName)
130133
}
134+
135+
metricsCh <- prometheus.MustNewConstMetric(lastUpdateDesc, prometheus.GaugeValue, float64(currentState.createdAt.Unix()))
131136
}
132137

133138
type state struct {
134139
prebuildMetrics []database.GetPrebuildMetricsRow
135140
snapshot *prebuilds.GlobalSnapshot
141+
createdAt time.Time
136142
}
137143

138144
// BackgroundFetch updates the metrics state every given interval.
@@ -157,6 +163,7 @@ func (mc *MetricsCollector) BackgroundFetch(ctx context.Context, updateInterval,
157163

158164
// UpdateState builds the current metrics state.
159165
func (mc *MetricsCollector) UpdateState(ctx context.Context, timeout time.Duration) error {
166+
start := time.Now()
160167
mc.logger.Debug(ctx, "fetching prebuilds metrics state")
161168
fetchCtx, fetchCancel := context.WithTimeout(ctx, timeout)
162169
defer fetchCancel()
@@ -170,11 +177,12 @@ func (mc *MetricsCollector) UpdateState(ctx context.Context, timeout time.Durati
170177
if err != nil {
171178
return xerrors.Errorf("snapshot state: %w", err)
172179
}
173-
mc.logger.Debug(ctx, "fetched prebuilds metrics state")
180+
mc.logger.Debug(ctx, "fetched prebuilds metrics state", slog.F("duration_secs", fmt.Sprintf("%.2f", time.Since(start).Seconds())))
174181

175182
mc.latestState.Store(&state{
176183
prebuildMetrics: prebuildMetrics,
177184
snapshot: snapshot,
185+
createdAt: time.Now(),
178186
})
179187
return nil
180188
}

enterprise/coderd/prebuilds/reconcile.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"database/sql"
66
"fmt"
77
"math"
8+
"sync"
89
"sync/atomic"
910
"time"
1011

@@ -87,10 +88,12 @@ func (c *StoreReconciler) Run(ctx context.Context) {
8788
slog.F("backoff_interval", c.cfg.ReconciliationBackoffInterval.String()),
8889
slog.F("backoff_lookback", c.cfg.ReconciliationBackoffLookback.String()))
8990

91+
var wg sync.WaitGroup
9092
ticker := c.clock.NewTicker(reconciliationInterval)
9193
defer ticker.Stop()
9294
defer func() {
9395
c.done <- struct{}{}
96+
wg.Wait()
9497
}()
9598

9699
// nolint:gocritic // Reconciliation Loop needs Prebuilds Orchestrator permissions.
@@ -99,7 +102,11 @@ func (c *StoreReconciler) Run(ctx context.Context) {
99102

100103
// Start updating metrics in the background.
101104
if c.metrics != nil {
102-
go c.metrics.BackgroundFetch(ctx, metricsUpdateInterval, metricsUpdateTimeout)
105+
wg.Add(1)
106+
go func() {
107+
defer wg.Done()
108+
c.metrics.BackgroundFetch(ctx, metricsUpdateInterval, metricsUpdateTimeout)
109+
}()
103110
}
104111

105112
// Everything is in place, reconciler can now be considered as running.

0 commit comments

Comments
 (0)
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