diff --git a/gocron.go b/gocron.go index b3c84a4..fb7adf7 100644 --- a/gocron.go +++ b/gocron.go @@ -56,6 +56,8 @@ func ChangeLoc(newLocation *time.Location) { // Job struct keeping information about job type Job struct { + ShouldDoImmediately bool // indicates that jobs should start before scheduling + mu *sync.Mutex interval uint64 // pause interval * unit bettween runs jobFunc string // the job jobFunc to run, func[jobFunc] @@ -67,7 +69,6 @@ type Job struct { funcs map[string]interface{} // Map for the function task store fparams map[string]([]interface{}) // Map for function and params of function err error - shouldDo bool // indicates that jobs should start before scheduling } // NewJob creates a new job with the time interval. @@ -103,7 +104,7 @@ func (j *Job) run() ([]reflect.Value, error) { } var result []reflect.Value - if j.shouldDo { + if j.ShouldDoImmediately { in := make([]reflect.Value, len(params)) for k, param := range params { // should check for nil items to avoid a panic @@ -257,7 +258,7 @@ func (j *Job) scheduleNextRun() error { // advance to next possible schedule for j.nextRun.Before(now) || j.nextRun.Before(j.lastRun) { - j.shouldDo = true + j.ShouldDoImmediately = true j.mu.Lock() j.nextRun = j.nextRun.Add(period) j.mu.Unlock() @@ -438,9 +439,12 @@ func (s *Scheduler) NextRun() (*Job, time.Time) { } // Every schedule a new periodic job with interval -func (s *Scheduler) Every(interval uint64, startImmediately bool) *Job { +func (s *Scheduler) Every(interval uint64, options ...func(*Job)) *Job { job := NewJob(interval) - job.shouldDo = startImmediately + for _, option := range options { + option(job) + } + s.mu.Lock() s.jobs = append(s.jobs, job) s.mu.Unlock() @@ -543,8 +547,12 @@ func (s *Scheduler) Start() chan bool { var defaultScheduler = NewScheduler() // Every schedules a new periodic job running in specific interval -func Every(interval uint64) *Job { - return defaultScheduler.Every(interval, false) +func Every(interval uint64, options ...func(*Job)) *Job { + job := defaultScheduler.Every(interval) + for _, option := range options { + option(job) + } + return job } // RunPending run all jobs that are scheduled to run diff --git a/gocron_test.go b/gocron_test.go index b18d8c7..053bd1e 100644 --- a/gocron_test.go +++ b/gocron_test.go @@ -6,6 +6,10 @@ import ( "time" ) +var defaultOption = func(j *Job) { + j.ShouldDoImmediately = true +} + func task() { fmt.Println("I am a running job.") } @@ -21,8 +25,9 @@ func assertEqualTime(name string, t *testing.T, actual, expected time.Time) { } func TestSecond(t *testing.T) { - defaultScheduler.Every(1, true).Second().Do(task) - defaultScheduler.Every(1, true).Second().Do(taskWithParams, 1, "hello") + + defaultScheduler.Every(1, defaultOption).Second().Do(task) + defaultScheduler.Every(1, defaultOption).Second().Do(taskWithParams, 1, "hello") stop := defaultScheduler.Start() time.Sleep(5 * time.Second) close(stop) @@ -114,7 +119,7 @@ func TestTaskAt(t *testing.T) { // Schedule every day At startAt := fmt.Sprintf("%02d:%02d", now.Hour(), now.Minute()+1) - dayJob := s.Every(1, true).Day().At(startAt) + dayJob := s.Every(1, defaultOption).Day().At(startAt) if err := dayJob.Err(); err != nil { t.Error(err) } @@ -149,19 +154,19 @@ func TestDaily(t *testing.T) { s := NewScheduler() // schedule next run 1 day - dayJob := s.Every(1, true).Day() + dayJob := s.Every(1, defaultOption).Day() dayJob.scheduleNextRun() exp := time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, loc) assertEqualTime("1 day", t, dayJob.nextRun, exp) // schedule next run 2 days - dayJob = s.Every(2, true).Days() + dayJob = s.Every(2, defaultOption).Days() dayJob.scheduleNextRun() exp = time.Date(now.Year(), now.Month(), now.Day()+2, 0, 0, 0, 0, loc) assertEqualTime("2 days", t, dayJob.nextRun, exp) // Job running longer than next schedule 1day 2 hours - dayJob = s.Every(1, true).Day() + dayJob = s.Every(1, defaultOption).Day() dayJob.lastRun = time.Date(now.Year(), now.Month(), now.Day(), now.Hour()+2, 0, 0, 0, loc) dayJob.scheduleNextRun() exp = time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, loc) @@ -171,7 +176,7 @@ func TestDaily(t *testing.T) { hour := now.Hour() - 2 minute := now.Minute() startAt := fmt.Sprintf("%02d:%02d", hour, minute) - dayJob = s.Every(1, true).Day().At(startAt) + dayJob = s.Every(1, defaultOption).Day().At(startAt) if err := dayJob.Err(); err != nil { t.Error(err) } @@ -191,19 +196,19 @@ func TestWeekdayAfterToday(t *testing.T) { var weekJob *Job switch now.Weekday() { case time.Monday: - weekJob = s.Every(1, true).Tuesday() + weekJob = s.Every(1, defaultOption).Tuesday() case time.Tuesday: - weekJob = s.Every(1, true).Wednesday() + weekJob = s.Every(1, defaultOption).Wednesday() case time.Wednesday: - weekJob = s.Every(1, true).Thursday() + weekJob = s.Every(1, defaultOption).Thursday() case time.Thursday: - weekJob = s.Every(1, true).Friday() + weekJob = s.Every(1, defaultOption).Friday() case time.Friday: - weekJob = s.Every(1, true).Saturday() + weekJob = s.Every(1, defaultOption).Saturday() case time.Saturday: - weekJob = s.Every(1, true).Sunday() + weekJob = s.Every(1, defaultOption).Sunday() case time.Sunday: - weekJob = s.Every(1, true).Monday() + weekJob = s.Every(1, defaultOption).Monday() } // First run @@ -229,19 +234,19 @@ func TestWeekdayBeforeToday(t *testing.T) { var weekJob *Job switch now.Weekday() { case time.Monday: - weekJob = s.Every(1, true).Sunday() + weekJob = s.Every(1, defaultOption).Sunday() case time.Tuesday: - weekJob = s.Every(1, true).Monday() + weekJob = s.Every(1, defaultOption).Monday() case time.Wednesday: - weekJob = s.Every(1, true).Tuesday() + weekJob = s.Every(1, defaultOption).Tuesday() case time.Thursday: - weekJob = s.Every(1, true).Wednesday() + weekJob = s.Every(1, defaultOption).Wednesday() case time.Friday: - weekJob = s.Every(1, true).Thursday() + weekJob = s.Every(1, defaultOption).Thursday() case time.Saturday: - weekJob = s.Every(1, true).Friday() + weekJob = s.Every(1, defaultOption).Friday() case time.Sunday: - weekJob = s.Every(1, true).Saturday() + weekJob = s.Every(1, defaultOption).Saturday() } weekJob.scheduleNextRun() @@ -270,37 +275,37 @@ func TestWeekdayAt(t *testing.T) { var weekJob *Job switch now.Weekday() { case time.Monday: - weekJob = s.Every(1, true).Tuesday().At(startAt) + weekJob = s.Every(1, defaultOption).Tuesday().At(startAt) if err := weekJob.Err(); err != nil { t.Error(err) } case time.Tuesday: - weekJob = s.Every(1, true).Wednesday().At(startAt) + weekJob = s.Every(1, defaultOption).Wednesday().At(startAt) if err := weekJob.Err(); err != nil { t.Error(err) } case time.Wednesday: - weekJob = s.Every(1, true).Thursday().At(startAt) + weekJob = s.Every(1, defaultOption).Thursday().At(startAt) if err := weekJob.Err(); err != nil { t.Error(err) } case time.Thursday: - weekJob = s.Every(1, true).Friday().At(startAt) + weekJob = s.Every(1, defaultOption).Friday().At(startAt) if err := weekJob.Err(); err != nil { t.Error(err) } case time.Friday: - weekJob = s.Every(1, true).Saturday().At(startAt) + weekJob = s.Every(1, defaultOption).Saturday().At(startAt) if err := weekJob.Err(); err != nil { t.Error(err) } case time.Saturday: - weekJob = s.Every(1, true).Sunday().At(startAt) + weekJob = s.Every(1, defaultOption).Sunday().At(startAt) if err := weekJob.Err(); err != nil { t.Error(err) } case time.Sunday: - weekJob = s.Every(1, true).Monday().At(startAt) + weekJob = s.Every(1, defaultOption).Monday().At(startAt) if err := weekJob.Err(); err != nil { t.Error(err) }