Skip to content

Commit

Permalink
start jobs immediately by default (#82)
Browse files Browse the repository at this point in the history
* start jobs immediately by default

* set startsimmediately as default in constructor, false in date/time places

* golint
  • Loading branch information
JohnRoesler authored Nov 29, 2020
1 parent dfa6300 commit 014228d
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 50 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ See also these two great articles:

If you want to chat, you can find us at Slack! [<img src="https://img.shields.io/badge/gophers-gocron-brightgreen?logo=slack">](https://gophers.slack.com/archives/CQ7T0T1FW)

# Examples:
## Examples:

```go
package main
Expand Down Expand Up @@ -71,7 +71,6 @@ func main() {
tag1 := []string{"tag1"}
tag2 := []string{"tag2"}


s2.Every(1).Week().SetTag(tag1).Do(task)
s2.Every(1).Week().SetTag(tag2).Do(task)

Expand All @@ -89,13 +88,15 @@ func main() {
s2.Every(1).Wednesday().At("1:01").Do(task)

// Begin job at a specific date/time.
// Attention: scheduler timezone has precedence over job's timezone!
t := time.Date(2019, time.November, 10, 15, 0, 0, 0, time.UTC)
s2.Every(1).Hour().StartAt(t).Do(task)

// use .StartImmediately() to run job upon scheduler start
s2.Every(1).Hour().StartImmediately().Do(task)
// Delay start of job
s2.Every(1).Hour().StartAt(time.Now().Add(time.Duration(1 * time.Hour)).Do(task)

// Deprecated: Jobs start immediately by default
// use StartImmediately() to run job upon scheduler start
s2.Every(1).Hour().StartImmediately().Do(task)

// NextRun gets the next running time
_, time := s2.NextRun()
Expand Down
3 changes: 2 additions & 1 deletion example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ func ExampleScheduler_StartBlocking() {
func ExampleScheduler_StartAsync() {
s := gocron.NewScheduler(time.UTC)
_, _ = s.Every(3).Seconds().Do(task)
<-s.StartAsync()
s.StartAsync()
}

// Deprecated: All jobs start immediately by default unless set to a specific date or time
func ExampleScheduler_StartImmediately() {
s := gocron.NewScheduler(time.UTC)
_, _ = s.Every(1).Hour().StartImmediately().Do(task)
Expand Down
13 changes: 7 additions & 6 deletions job.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ type runConfig struct {
// NewJob creates a new Job with the provided interval
func NewJob(interval uint64) *Job {
return &Job{
interval: jobInterval(interval),
lastRun: time.Time{},
nextRun: time.Time{},
funcs: make(map[string]interface{}),
fparams: make(map[string][]interface{}),
tags: []string{},
interval: jobInterval(interval),
lastRun: time.Time{},
nextRun: time.Time{},
funcs: make(map[string]interface{}),
fparams: make(map[string][]interface{}),
tags: []string{},
startsImmediately: true,
}
}

Expand Down
30 changes: 20 additions & 10 deletions scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,17 @@ func (s *Scheduler) scheduleNextRun(job *Job) {
defer job.Unlock()
now := s.time.Now(s.loc)

if job.startsImmediately {
job.nextRun = now
job.startsImmediately = false
return
if job.neverRan() {
if !job.nextRun.IsZero() {
return // scheduled for future run and should skip scheduling
}
// default is for jobs to start immediately unless scheduled at a specific time or day
if job.startsImmediately {
job.nextRun = now
return
}
}

if job.neverRan() && !job.nextRun.IsZero() {
return // scheduled for future run and should skip scheduling
}
job.lastRun = now

durationToNextRun := s.durationToNextRun(job)
Expand Down Expand Up @@ -422,6 +424,7 @@ func (s *Scheduler) At(t string) *Scheduler {
}
// save atTime start as duration from midnight
j.atTime = time.Duration(hour)*time.Hour + time.Duration(min)*time.Minute + time.Duration(sec)*time.Second
j.startsImmediately = false
return s
}

Expand All @@ -434,11 +437,14 @@ func (s *Scheduler) SetTag(t []string) *Scheduler {

// StartAt schedules the next run of the Job
func (s *Scheduler) StartAt(t time.Time) *Scheduler {
s.getCurrentJob().nextRun = t
job := s.getCurrentJob()
job.nextRun = t
job.startsImmediately = false
return s
}

// StartImmediately sets the Jobs next run as soon as the scheduler starts
// Deprecated: Jobs start immediately by default unless a specific start day or time is set
func (s *Scheduler) StartImmediately() *Scheduler {
job := s.getCurrentJob()
job.startsImmediately = true
Expand Down Expand Up @@ -520,7 +526,9 @@ func (s *Scheduler) Month(dayOfTheMonth int) *Scheduler {

// Months sets the unit with months
func (s *Scheduler) Months(dayOfTheMonth int) *Scheduler {
s.getCurrentJob().dayOfTheMonth = dayOfTheMonth
job := s.getCurrentJob()
job.dayOfTheMonth = dayOfTheMonth
job.startsImmediately = false
s.setUnit(months)
return s
}
Expand All @@ -532,7 +540,9 @@ func (s *Scheduler) Months(dayOfTheMonth int) *Scheduler {

// Weekday sets the start with a specific weekday weekday
func (s *Scheduler) Weekday(startDay time.Weekday) *Scheduler {
s.getCurrentJob().scheduledWeekday = &startDay
job := s.getCurrentJob()
job.scheduledWeekday = &startDay
job.startsImmediately = false
s.setUnit(weeks)
return s
}
Expand Down
68 changes: 40 additions & 28 deletions scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestExecutionSeconds(t *testing.T) {
var (
executions []int64
interval uint64 = 2
expectedExecutions = 3
expectedExecutions = 4
)

runTime := time.Duration(6 * time.Second)
Expand Down Expand Up @@ -135,22 +135,50 @@ func TestAtFuture(t *testing.T) {
assert.Equal(t, false, shouldBeFalse, "Day job was not expected to run as it was in the future")
}

func schedulerForNextWeekdayEveryNTimes(weekday time.Weekday, n uint64, s *Scheduler) *Scheduler {
func schedulerForNextOrPreviousWeekdayEveryNTimes(weekday time.Weekday, next bool, n uint64, s *Scheduler) *Scheduler {
switch weekday {
case time.Monday:
s = s.Every(n).Tuesday()
if next {
s = s.Every(n).Tuesday()
} else {
s = s.Every(n).Sunday()
}
case time.Tuesday:
s = s.Every(n).Wednesday()
if next {
s = s.Every(n).Wednesday()
} else {
s = s.Every(n).Monday()
}
case time.Wednesday:
s = s.Every(n).Thursday()
if next {
s = s.Every(n).Thursday()
} else {
s = s.Every(n).Tuesday()
}
case time.Thursday:
s = s.Every(n).Friday()
if next {
s = s.Every(n).Friday()
} else {
s = s.Every(n).Wednesday()
}
case time.Friday:
s = s.Every(n).Saturday()
if next {
s = s.Every(n).Saturday()
} else {
s = s.Every(n).Thursday()
}
case time.Saturday:
s = s.Every(n).Sunday()
if next {
s = s.Every(n).Sunday()
} else {
s = s.Every(n).Friday()
}
case time.Sunday:
s = s.Every(n).Monday()
if next {
s = s.Every(n).Monday()
} else {
s = s.Every(n).Saturday()
}
}
return s
}
Expand All @@ -159,23 +187,7 @@ func TestWeekdayBeforeToday(t *testing.T) {
now := time.Now().In(time.UTC)
s := NewScheduler(time.UTC)

// Schedule job at day before
switch now.Weekday() {
case time.Monday:
s = s.Every(1).Sunday()
case time.Tuesday:
s = s.Every(1).Monday()
case time.Wednesday:
s = s.Every(1).Tuesday()
case time.Thursday:
s = s.Every(1).Wednesday()
case time.Friday:
s = s.Every(1).Thursday()
case time.Saturday:
s = s.Every(1).Friday()
case time.Sunday:
s = s.Every(1).Saturday()
}
s = schedulerForNextOrPreviousWeekdayEveryNTimes(now.Weekday(), false, 1, s)
weekJob, _ := s.Do(task)
s.scheduleNextRun(weekJob)
sixDaysFromNow := now.AddDate(0, 0, 6)
Expand All @@ -188,7 +200,7 @@ func TestWeekdayAt(t *testing.T) {
t.Run("asserts weekday scheduling starts at the current week", func(t *testing.T) {
s := NewScheduler(time.UTC)
now := time.Now().UTC()
s = schedulerForNextWeekdayEveryNTimes(now.Weekday(), 1, s)
s = schedulerForNextOrPreviousWeekdayEveryNTimes(now.Weekday(), true, 1, s)
weekdayJob, _ := s.Do(task)

s.scheduleNextRun(weekdayJob)
Expand Down Expand Up @@ -386,7 +398,7 @@ func TestScheduler_StartAt(t *testing.T) {
job, _ = scheduler.Every(3).Seconds().Do(func() {})
scheduler.scheduleNextRun(job)
_, nextRun = scheduler.NextRun()
assert.Equal(t, now.Add(time.Second*3).Second(), nextRun.Second())
assert.Equal(t, now.Second(), nextRun.Second())
}

func TestScheduler_CalculateNextRun(t *testing.T) {
Expand Down

0 comments on commit 014228d

Please sign in to comment.