| 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() |
| } |
| }) |
| } |