in silence/silence.go [378:444]
func (s *Silences) Maintenance(interval time.Duration, snapf string, stopc <-chan struct{}, override MaintenanceFunc) {
if interval == 0 || stopc == nil {
level.Error(s.logger).Log("msg", "interval or stop signal are missing - not running maintenance")
return
}
t := s.clock.Ticker(interval)
defer t.Stop()
var doMaintenance MaintenanceFunc
doMaintenance = func() (int64, error) {
var size int64
if _, err := s.GC(); err != nil {
return size, err
}
if snapf == "" {
return size, nil
}
f, err := openReplace(snapf)
if err != nil {
return size, err
}
if size, err = s.Snapshot(f); err != nil {
f.Close()
return size, err
}
return size, f.Close()
}
if override != nil {
doMaintenance = override
}
runMaintenance := func(do MaintenanceFunc) error {
s.metrics.maintenanceTotal.Inc()
level.Debug(s.logger).Log("msg", "Running maintenance")
start := s.nowUTC()
size, err := do()
s.metrics.snapshotSize.Set(float64(size))
if err != nil {
s.metrics.maintenanceErrorsTotal.Inc()
return err
}
level.Debug(s.logger).Log("msg", "Maintenance done", "duration", s.clock.Since(start), "size", size)
return nil
}
Loop:
for {
select {
case <-stopc:
break Loop
case <-t.C:
if err := runMaintenance(doMaintenance); err != nil {
level.Info(s.logger).Log("msg", "Running maintenance failed", "err", err)
}
}
}
// No need for final maintenance if we don't want to snapshot.
if snapf == "" {
return
}
if err := runMaintenance(doMaintenance); err != nil {
level.Info(s.logger).Log("msg", "Creating shutdown snapshot failed", "err", err)
}
}