Skip to content

Commit daf5304

Browse files
authored
Merge pull request #67 from arjunmahishi/feature/control-run-count
Add a new Job method called 'LimitRunsTo'
2 parents 3526e7c + 6d62034 commit daf5304

File tree

4 files changed

+86
-1
lines changed

4 files changed

+86
-1
lines changed

example_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,10 @@ func ExampleScheduler_Clear() {
8888
// 3
8989
// 0
9090
}
91+
92+
func ExampleJob_LimitRunsTo() {
93+
s := gocron.NewScheduler(time.UTC)
94+
job, _ := s.Every(1).Second().Do(task)
95+
job.LimitRunsTo(2)
96+
s.StartAsync()
97+
}

job.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ type Job struct {
2121
fparams map[string][]interface{} // Map for function and params of function
2222
lock bool // lock the Job from running at same time form multiple instances
2323
tags []string // allow the user to tag Jobs with certain labels
24+
runConfig runConfig // configuration for how many times to run the job
25+
runCount int // number of time the job ran
26+
}
27+
28+
type runConfig struct {
29+
finiteRuns bool
30+
maxRuns int
2431
}
2532

2633
// NewJob creates a new Job with the provided interval
@@ -38,6 +45,7 @@ func NewJob(interval uint64) *Job {
3845
// Run the Job and immediately reschedule it
3946
func (j *Job) run() {
4047
callJobFuncWithParams(j.funcs[j.jobFunc], j.fparams[j.jobFunc])
48+
j.runCount++
4149
}
4250

4351
func (j Job) neverRan() bool {
@@ -93,3 +101,19 @@ func (j *Job) Weekday() (time.Weekday, error) {
93101
}
94102
return *j.scheduledWeekday, nil
95103
}
104+
105+
// LimitRunsTo limits the number of executions of this
106+
// job to n. However, the job will still remain in the
107+
// scheduler
108+
func (j *Job) LimitRunsTo(n int) {
109+
j.runConfig = runConfig{
110+
finiteRuns: true,
111+
maxRuns: n,
112+
}
113+
}
114+
115+
// shouldRun eveluates if this job should run again
116+
// based on the runConfig
117+
func (j *Job) shouldRun() bool {
118+
return !j.runConfig.finiteRuns || j.runCount < j.runConfig.maxRuns
119+
}

job_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,57 @@ func TestGetWeekday(t *testing.T) {
5353
})
5454
}
5555
}
56+
57+
func TestJob_shouldRunAgain(t *testing.T) {
58+
tests := []struct {
59+
name string
60+
runConfig runConfig
61+
runCount int
62+
want bool
63+
}{
64+
{
65+
name: "should run again (infinite)",
66+
runConfig: runConfig{finiteRuns: false},
67+
want: true,
68+
},
69+
{
70+
name: "should run again (finite)",
71+
runConfig: runConfig{finiteRuns: true, maxRuns: 2},
72+
runCount: 1,
73+
want: true,
74+
},
75+
{
76+
name: "shouldn't run again #1",
77+
runConfig: runConfig{finiteRuns: true, maxRuns: 2},
78+
runCount: 2,
79+
want: false,
80+
},
81+
{
82+
name: "shouldn't run again #2",
83+
runConfig: runConfig{finiteRuns: true, maxRuns: 2},
84+
runCount: 4,
85+
want: false,
86+
},
87+
}
88+
for _, tt := range tests {
89+
t.Run(tt.name, func(t *testing.T) {
90+
j := &Job{
91+
runConfig: tt.runConfig,
92+
runCount: tt.runCount,
93+
}
94+
if got := j.shouldRun(); got != tt.want {
95+
t.Errorf("Job.shouldRunAgain() = %v, want %v", got, tt.want)
96+
}
97+
})
98+
}
99+
}
100+
101+
func TestJob_LimitRunsTo(t *testing.T) {
102+
j, _ := NewScheduler(time.Local).Every(1).Second().Do(func() {})
103+
j.LimitRunsTo(2)
104+
assert.Equal(t, j.shouldRun(), true, "Expecting it to run again")
105+
j.run()
106+
assert.Equal(t, j.shouldRun(), true, "Expecting it to run again")
107+
j.run()
108+
assert.Equal(t, j.shouldRun(), false, "Not expecting it to run again")
109+
}

scheduler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ func (s *Scheduler) StartImmediately() *Scheduler {
435435

436436
// shouldRun returns true if the Job should be run now
437437
func (s *Scheduler) shouldRun(j *Job) bool {
438-
return s.time.Now(s.loc).Unix() >= j.nextRun.Unix()
438+
return j.shouldRun() && s.time.Now(s.loc).Unix() >= j.nextRun.Unix()
439439
}
440440

441441
// setUnit sets the unit type

0 commit comments

Comments
 (0)