in timed/timed.go [67:91]
func Periodic(ctx canceler, period time.Duration, fn func() error) error {
ticker := time.NewTicker(period)
defer ticker.Stop()
done := ctx.Done()
for {
// always check for cancel first, to not accidentally trigger another run if
// the context is already cancelled, but we have already received another
// ticker signal
select {
case <-done:
return ctx.Err()
default:
}
select {
case <-ticker.C:
if err := fn(); err != nil {
return err
}
case <-done:
return ctx.Err()
}
}
}