Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5da546e

Browse files
committed
chore: improvements
Signed-off-by: Danny Kopping <dannykopping@gmail.com>
1 parent562b56d commit5da546e

File tree

2 files changed

+40
-16
lines changed

2 files changed

+40
-16
lines changed

‎enterprise/coderd/prebuilds/metricscollector.go

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package prebuilds
22

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

89
"github.com/prometheus/client_golang/prometheus"
@@ -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 (
@@ -69,7 +75,9 @@ type MetricsCollector struct {
6975
logger slog.Logger
7076
snapshotter prebuilds.StateSnapshotter
7177

72-
latestState atomic.Pointer[state]
78+
latestState*state
79+
latestStateUpdatedAt time.Time
80+
latestStateMu sync.Mutex
7381
}
7482

7583
var_ prometheus.Collector=new(MetricsCollector)
@@ -91,35 +99,36 @@ func (*MetricsCollector) Describe(descCh chan<- *prometheus.Desc) {
9199
descCh<-desiredPrebuildsDesc
92100
descCh<-runningPrebuildsDesc
93101
descCh<-eligiblePrebuildsDesc
102+
descCh<-lastUpdateDesc
94103
}
95104

96105
// Collect uses the cached state to set configured metrics.
97106
// The state is cached because this function can be called multiple times per second and retrieving the current state
98107
// is an expensive operation.
99108
func (mc*MetricsCollector)Collect(metricsChchan<- prometheus.Metric) {
100-
// nolint:gocritic // We need to set an authz context to read metrics from the db.
101-
ctx:=dbauthz.AsPrebuildsOrchestrator(context.Background())
109+
// Prevent the state from changing while a collection is occurring.
110+
mc.latestStateMu.Lock()
111+
defermc.latestStateMu.Unlock()
102112

103-
currentState:=mc.latestState.Load()
104-
ifcurrentState==nil {
105-
mc.logger.Warn(ctx,"failed to set prebuilds metrics; state not set")
113+
ifmc.latestState==nil {
114+
mc.logger.Warn(context.Background(),"failed to set prebuilds metrics; state not set")
106115
return
107116
}
108117

109-
for_,metric:=rangecurrentState.prebuildMetrics {
118+
for_,metric:=rangemc.latestState.prebuildMetrics {
110119
metricsCh<-prometheus.MustNewConstMetric(createdPrebuildsDesc,prometheus.CounterValue,float64(metric.CreatedCount),metric.TemplateName,metric.PresetName,metric.OrganizationName)
111120
metricsCh<-prometheus.MustNewConstMetric(failedPrebuildsDesc,prometheus.CounterValue,float64(metric.FailedCount),metric.TemplateName,metric.PresetName,metric.OrganizationName)
112121
metricsCh<-prometheus.MustNewConstMetric(claimedPrebuildsDesc,prometheus.CounterValue,float64(metric.ClaimedCount),metric.TemplateName,metric.PresetName,metric.OrganizationName)
113122
}
114123

115-
for_,preset:=rangecurrentState.snapshot.Presets {
124+
for_,preset:=rangemc.latestState.snapshot.Presets {
116125
if!preset.UsingActiveVersion {
117126
continue
118127
}
119128

120-
presetSnapshot,err:=currentState.snapshot.FilterByPreset(preset.ID)
129+
presetSnapshot,err:=mc.latestState.snapshot.FilterByPreset(preset.ID)
121130
iferr!=nil {
122-
mc.logger.Error(ctx,"failed to filter by preset",slog.Error(err))
131+
mc.logger.Error(context.Background(),"failed to filter by preset",slog.Error(err))
123132
continue
124133
}
125134
state:=presetSnapshot.CalculateState()
@@ -128,6 +137,8 @@ func (mc *MetricsCollector) Collect(metricsCh chan<- prometheus.Metric) {
128137
metricsCh<-prometheus.MustNewConstMetric(runningPrebuildsDesc,prometheus.GaugeValue,float64(state.Actual),preset.TemplateName,preset.Name,preset.OrganizationName)
129138
metricsCh<-prometheus.MustNewConstMetric(eligiblePrebuildsDesc,prometheus.GaugeValue,float64(state.Eligible),preset.TemplateName,preset.Name,preset.OrganizationName)
130139
}
140+
141+
metricsCh<-prometheus.MustNewConstMetric(lastUpdateDesc,prometheus.GaugeValue,float64(mc.latestStateUpdatedAt.Unix()))
131142
}
132143

133144
typestatestruct {
@@ -157,6 +168,11 @@ func (mc *MetricsCollector) BackgroundFetch(ctx context.Context, updateInterval,
157168

158169
// UpdateState builds the current metrics state.
159170
func (mc*MetricsCollector)UpdateState(ctx context.Context,timeout time.Duration)error {
171+
// Prevent collection from occurring while state is updating.
172+
mc.latestStateMu.Lock()
173+
defermc.latestStateMu.Unlock()
174+
175+
start:=time.Now()
160176
mc.logger.Debug(ctx,"fetching prebuilds metrics state")
161177
fetchCtx,fetchCancel:=context.WithTimeout(ctx,timeout)
162178
deferfetchCancel()
@@ -170,11 +186,12 @@ func (mc *MetricsCollector) UpdateState(ctx context.Context, timeout time.Durati
170186
iferr!=nil {
171187
returnxerrors.Errorf("snapshot state: %w",err)
172188
}
173-
mc.logger.Debug(ctx,"fetched prebuilds metrics state")
189+
mc.logger.Debug(ctx,"fetched prebuilds metrics state",slog.F("duration_secs",fmt.Sprintf("%.2f",time.Since(start).Seconds())))
174190

175-
mc.latestState.Store(&state{
191+
mc.latestState=&state{
176192
prebuildMetrics:prebuildMetrics,
177193
snapshot:snapshot,
178-
})
194+
}
195+
mc.latestStateUpdatedAt=time.Now()
179196
returnnil
180197
}

‎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+
varwg sync.WaitGroup
9092
ticker:=c.clock.NewTicker(reconciliationInterval)
9193
deferticker.Stop()
9294
deferfunc() {
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
ifc.metrics!=nil {
102-
goc.metrics.BackgroundFetch(ctx,metricsUpdateInterval,metricsUpdateTimeout)
105+
wg.Add(1)
106+
gofunc() {
107+
deferwg.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)

[8]ページ先頭

©2009-2025 Movatter.jp