| 182 | } |
| 183 | |
| 184 | func (c *Cache) run(ctx context.Context, name string, interval time.Duration, refresh func(context.Context) error) { |
| 185 | logger := c.log.With(slog.F("name", name), slog.F("interval", interval)) |
| 186 | |
| 187 | tickerFunc := func() error { |
| 188 | start := c.clock.Now() |
| 189 | for r := retry.New(time.Millisecond*100, time.Minute); r.Wait(ctx); { |
| 190 | err := refresh(ctx) |
| 191 | if err != nil { |
| 192 | if ctx.Err() != nil { |
| 193 | return nil |
| 194 | } |
| 195 | if xerrors.Is(err, sql.ErrNoRows) { |
| 196 | break |
| 197 | } |
| 198 | logger.Error(ctx, "refresh metrics failed", slog.Error(err)) |
| 199 | continue |
| 200 | } |
| 201 | logger.Debug(ctx, "metrics refreshed", slog.F("took", c.clock.Since(start))) |
| 202 | break |
| 203 | } |
| 204 | return nil |
| 205 | } |
| 206 | |
| 207 | // Call once immediately before starting ticker |
| 208 | _ = tickerFunc() |
| 209 | |
| 210 | tkr := c.clock.TickerFunc(ctx, interval, tickerFunc, "metricscache", name) |
| 211 | _ = tkr.Wait() |
| 212 | } |
| 213 | |
| 214 | func (c *Cache) Close() error { |
| 215 | c.cancel() |