GoToSocial/vendor/codeberg.org/gruf/go-sched/timing.go

93 lines
2.0 KiB
Go

package sched
import (
"time"
)
var (
// zerotime is zero time.Time (unix epoch).
zerotime = time.Time{}
// emptytiming is a global timingempty to check against.
emptytiming = timingempty{}
)
// Timing provides scheduling for a Job, determining the next time
// for given current time that execution is required. Please note that
// calls to .Next() may alter the results of the next call, and should
// only be called by the Scheduler.
type Timing interface {
Next(time.Time) time.Time
}
// timingempty is a 'zero' Timing implementation that always returns zero time.
type timingempty struct{}
func (timingempty) Next(time.Time) time.Time {
return zerotime
}
// Once implements Timing to provide a run-once Job execution.
type Once time.Time
func (o *Once) Next(time.Time) time.Time {
ret := *(*time.Time)(o)
*o = Once(zerotime) // reset
return ret
}
// Periodic implements Timing to provide a recurring Job execution.
type Periodic time.Duration
func (p Periodic) Next(now time.Time) time.Time {
return now.Add(time.Duration(p))
}
// PeriodicAt implements Timing to provide a recurring Job execution starting at 'Once' time.
type PeriodicAt struct {
Once Once
Period Periodic
}
func (p *PeriodicAt) Next(now time.Time) time.Time {
if next := p.Once.Next(now); !next.IsZero() {
return next
}
return p.Period.Next(now)
}
// TimingWrap allows combining two different Timing implementations.
type TimingWrap struct {
Outer Timing
Inner Timing
// determined next times
outerNext time.Time
innerNext time.Time
}
func (t *TimingWrap) Next(now time.Time) time.Time {
if t.outerNext.IsZero() {
// Regenerate outermost next run time
t.outerNext = t.Outer.Next(now)
}
if t.innerNext.IsZero() {
// Regenerate innermost next run time
t.innerNext = t.Inner.Next(now)
}
// If outer comes before inner, return outer
if t.outerNext != zerotime &&
t.outerNext.Before(t.innerNext) {
next := t.outerNext
t.outerNext = zerotime
return next
}
// Else, return inner
next := t.innerNext
t.innerNext = zerotime
return next
}