blob: 3a07af9e9e4508e785f430e060882c678534b702 [file] [log] [blame]
package metrics_cleanup
/*
Package metrics_cleanup provides helpers for producing metrics on the fly
and cleaning them up.
*/
import (
"context"
"time"
"go.skia.org/infra/go/metrics2"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/go/util"
)
// DoMetricsWithCleanup encapsulates the process of running a function to
// generate on-the-fly metrics, tracking success or failure of that generation,
// and cleaning up metrics which no longer exist.
func DoMetricsWithCleanup(ctx context.Context, frequency time.Duration, lv metrics2.Liveness, doMetrics func(context.Context, time.Time) ([]metrics2.Int64Metric, error)) {
oldMetrics := map[metrics2.Int64Metric]struct{}{}
go util.RepeatCtx(ctx, frequency, func(ctx context.Context) {
newMetrics, err := doMetrics(ctx, time.Now())
if err != nil {
sklog.Errorf("Failed to update metrics: %s", err)
} else {
newMetricsMap := make(map[metrics2.Int64Metric]struct{}, len(newMetrics))
for _, m := range newMetrics {
newMetricsMap[m] = struct{}{}
}
var cleanup []metrics2.Int64Metric
for m := range oldMetrics {
if _, ok := newMetricsMap[m]; !ok {
cleanup = append(cleanup, m)
}
}
if len(cleanup) > 0 {
failedDelete := []metrics2.Int64Metric{}
for m := range oldMetrics {
if err := m.Delete(); err != nil {
sklog.Warningf("Failed to delete metric: %s", err)
failedDelete = append(failedDelete, m)
}
}
for _, m := range failedDelete {
newMetricsMap[m] = struct{}{}
}
}
oldMetrics = newMetricsMap
lv.Reset()
}
})
}