Skip to content

Commit

Permalink
add CustomTimer allowing overriding of the time.AfterFunc (#381)
Browse files Browse the repository at this point in the history
* add CustomTimer allowing overriding of the time.AfterFunc

* lint
  • Loading branch information
JohnRoesler authored Aug 23, 2022
1 parent 5d9071a commit 3272c21
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
13 changes: 13 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,19 @@ func ExampleScheduler_CustomTime() {
// s.CustomTime(mct)
}

func ExampleScheduler_CustomTimer() {
s := gocron.NewScheduler(time.UTC)
s.CustomTimer(func(d time.Duration, f func()) *time.Timer {
// force jobs with 1 minute interval to run every second
if d == time.Minute {
d = time.Second
}
return time.AfterFunc(d, f)
})
// this job will run every 1 second
_, _ = s.Every("1m").Do(task)
}

func ExampleScheduler_Day() {
s := gocron.NewScheduler(time.UTC)

Expand Down
13 changes: 11 additions & 2 deletions scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ type Scheduler struct {
running bool // represents if the scheduler is running at the moment or not

time TimeWrapper // wrapper around time.Time
executor *executor // executes jobs passed via chan
timer func(d time.Duration, f func()) *time.Timer
executor *executor // executes jobs passed via chan

tags sync.Map // for storing tags when unique tags is set

Expand Down Expand Up @@ -55,6 +56,7 @@ func NewScheduler(loc *time.Location) *Scheduler {
time: &trueTime{},
executor: &executor,
tagsUnique: false,
timer: afterFunc,
}
}

Expand Down Expand Up @@ -569,7 +571,7 @@ func (s *Scheduler) runContinuous(job *Job) {
s.run(job)
}

job.setTimer(time.AfterFunc(next.duration, func() {
job.setTimer(s.timer(next.duration, func() {
if !next.dateTime.IsZero() {
for {
n := s.now().UnixNano() - next.dateTime.UnixNano()
Expand Down Expand Up @@ -1303,6 +1305,13 @@ func (s *Scheduler) CustomTime(customTimeWrapper TimeWrapper) {
s.time = customTimeWrapper
}

// CustomTimer takes in a function that mirrors the time.AfterFunc
// This is used to mock the time.AfterFunc function used by the scheduler
// for testing long intervals in a short amount of time.
func (s *Scheduler) CustomTimer(customTimer func(d time.Duration, f func()) *time.Timer) {
s.timer = customTimer
}

func (s *Scheduler) StopBlockingChan() {
s.startBlockingStopChanMutex.Lock()
if s.startBlockingStopChan != nil {
Expand Down
6 changes: 6 additions & 0 deletions timeHelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,9 @@ func (t *trueTime) Unix(sec int64, nsec int64) time.Time {
func (t *trueTime) Sleep(d time.Duration) {
time.Sleep(d)
}

// afterFunc proxies the time.AfterFunc function.
// This allows it to be mocked for testing.
func afterFunc(d time.Duration, f func()) *time.Timer {
return time.AfterFunc(d, f)
}

0 comments on commit 3272c21

Please sign in to comment.