Skip to content

Commit 69de418

Browse files
authored
Merge pull request #12 from arjunmahishi/feature/timeHelper-interface
add timeHelper interface to avoid direct coupling with the time package
2 parents 9978274 + 40f146e commit 69de418

File tree

3 files changed

+53
-11
lines changed

3 files changed

+53
-11
lines changed

job.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,32 @@ type Job struct {
2929
fparams map[string][]interface{} // Map for function and params of function
3030
lock bool // lock the job from running at same time form multiple instances
3131
tags []string // allow the user to tag jobs with certain labels
32+
time timeHelper // an instance of timeHelper to interact with the time package
3233
}
3334

3435
// NewJob creates a new job with the time interval.
3536
func NewJob(interval uint64) *Job {
37+
th := newTimeHelper()
3638
return &Job{
3739
interval: interval,
38-
lastRun: time.Unix(0, 0),
39-
nextRun: time.Unix(0, 0),
40+
lastRun: th.Unix(0, 0),
41+
nextRun: th.Unix(0, 0),
4042
startDay: time.Sunday,
4143
funcs: make(map[string]interface{}),
4244
fparams: make(map[string][]interface{}),
4345
tags: []string{},
46+
time: th,
4447
}
4548
}
4649

4750
// True if the job should be run now
4851
func (j *Job) shouldRun() bool {
49-
return time.Now().Unix() >= j.nextRun.Unix()
52+
return j.time.Now().Unix() >= j.nextRun.Unix()
5053
}
5154

5255
//Run the job and immediately reschedule it
5356
func (j *Job) run() {
54-
j.lastRun = time.Now()
57+
j.lastRun = j.time.Now()
5558
go callJobFuncWithParams(j.funcs[j.jobFunc], j.fparams[j.jobFunc])
5659
}
5760

scheduler.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,23 @@ import (
1212
type Scheduler struct {
1313
jobs []*Job
1414
loc *time.Location
15+
time timeHelper // an instance of timeHelper to interact with the time package
1516
}
1617

1718
// NewScheduler creates a new scheduler
1819
func NewScheduler(loc *time.Location) *Scheduler {
1920
return &Scheduler{
2021
jobs: newEmptyJobSlice(),
2122
loc: loc,
23+
time: newTimeHelper(),
2224
}
2325
}
2426

2527
// Start all the pending jobs
2628
// Add seconds ticker
2729
func (s *Scheduler) Start() chan struct{} {
2830
stopped := make(chan struct{})
29-
ticker := time.NewTicker(1 * time.Second)
31+
ticker := s.time.NewTicker(1 * time.Second)
3032

3133
go func() {
3234
for {
@@ -67,8 +69,8 @@ func (s *Scheduler) ChangeLoc(newLocation *time.Location) {
6769

6870
// scheduleNextRun Compute the instant when this job should run next
6971
func (s *Scheduler) scheduleNextRun(j *Job) error {
70-
now := time.Now().In(s.loc)
71-
if j.lastRun == time.Unix(0, 0) {
72+
now := s.time.Now().In(s.loc)
73+
if j.lastRun == s.time.Unix(0, 0) {
7274
j.lastRun = now
7375
}
7476

@@ -107,7 +109,7 @@ func (s *Scheduler) scheduleNextRun(j *Job) error {
107109

108110
// roundToMidnight truncate time to midnight
109111
func (s *Scheduler) roundToMidnight(t time.Time) time.Time {
110-
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, s.loc)
112+
return s.time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, s.loc)
111113
}
112114

113115
// Get the current runnable jobs, which shouldRun is True
@@ -127,7 +129,7 @@ func (s *Scheduler) getRunnableJobs() []*Job {
127129
// NextRun datetime when the next job should run.
128130
func (s *Scheduler) NextRun() (*Job, time.Time) {
129131
if len(s.jobs) <= 0 {
130-
return nil, time.Now()
132+
return nil, s.time.Now()
131133
}
132134
sort.Sort(s)
133135
return s.jobs[0], s.jobs[0].nextRun
@@ -178,7 +180,7 @@ func (s *Scheduler) RunAllWithDelay(d int) {
178180
if err != nil {
179181
continue
180182
}
181-
time.Sleep(time.Duration(d) * time.Second)
183+
s.time.Sleep(time.Duration(d) * time.Second)
182184
}
183185
}
184186

@@ -288,7 +290,7 @@ func (s *Scheduler) StartAt(t time.Time) *Scheduler {
288290
// StartImmediately sets the jobs next run as soon as the scheduler starts
289291
func (s *Scheduler) StartImmediately() *Scheduler {
290292
job := s.getCurrentJob()
291-
job.nextRun = time.Now().In(s.loc)
293+
job.nextRun = s.time.Now().In(s.loc)
292294
job.startsImmediately = true
293295
return s
294296
}

timeHelper.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package gocron
2+
3+
import "time"
4+
5+
type timeHelper interface {
6+
Now() time.Time
7+
Unix(int64, int64) time.Time
8+
Sleep(time.Duration)
9+
Date(int, time.Month, int, int, int, int, int, *time.Location) time.Time
10+
NewTicker(time.Duration) *time.Ticker
11+
}
12+
13+
func newTimeHelper() timeHelper {
14+
return &trueTime{}
15+
}
16+
17+
type trueTime struct{}
18+
19+
func (t *trueTime) Now() time.Time {
20+
return time.Now()
21+
}
22+
23+
func (t *trueTime) Unix(sec int64, nsec int64) time.Time {
24+
return time.Unix(sec, nsec)
25+
}
26+
27+
func (t *trueTime) Sleep(d time.Duration) {
28+
time.Sleep(d)
29+
}
30+
31+
func (t *trueTime) Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) time.Time {
32+
return time.Date(year, month, day, hour, min, sec, nsec, loc)
33+
}
34+
35+
func (t *trueTime) NewTicker(d time.Duration) *time.Ticker {
36+
return time.NewTicker(d)
37+
}

0 commit comments

Comments
 (0)