scron/time.go
kekskurse 3e5b5e1ecf init
2025-07-31 03:01:56 +02:00

53 lines
1.3 KiB
Go

package main
import "time"
type TimeProvider interface {
Now() time.Time
Sleep(d time.Duration)
NewTicker(d time.Duration) Ticker
}
type Ticker interface {
C() <-chan time.Time
Stop()
}
type realTimeProvider struct{}
func (realTimeProvider) Now() time.Time { return time.Now() }
func (realTimeProvider) Sleep(d time.Duration) { time.Sleep(d) }
func (realTimeProvider) NewTicker(d time.Duration) Ticker { return realTicker{time.NewTicker(d)} }
type realTicker struct {
*time.Ticker
}
func (rt realTicker) C() <-chan time.Time { return rt.Ticker.C }
// Return ticker for cron which tick at 0 and ticker for reloading config ticking 10 secounds before
func createTickers(tp TimeProvider) (<-chan time.Time, <-chan time.Time) {
nextTick := func(targetSecond int) time.Duration {
now := tp.Now()
next := now.Truncate(time.Minute).Add(time.Duration(targetSecond) * time.Second)
if !next.After(now) {
next = next.Add(time.Minute)
}
return next.Sub(now)
}
tickAt := func(targetSecond int) <-chan time.Time {
ch := make(chan time.Time)
go func() {
tp.Sleep(nextTick(targetSecond))
ticker := tp.NewTicker(time.Minute)
for {
ch <- tp.Now()
<-ticker.C()
}
}()
return ch
}
return tickAt(0), tickAt(50)
}