浏览代码

modified condition to select jobs to run in current loop

Select all exprired jobs instead of exact match job next time running time.
Bulat Gaifullin 8 年之前
父节点
当前提交
f9402aa2d8
共有 2 个文件被更改,包括 32 次插入8 次删除
  1. 12 8
      cron.go
  2. 20 0
      cron_test.go

+ 12 - 8
cron.go

@@ -165,11 +165,11 @@ func (c *Cron) runWithRecovery(j Job) {
 	j.Run()
 }
 
-// Run the scheduler.. this is private just due to the need to synchronize
+// Run the scheduler. this is private just due to the need to synchronize
 // access to the 'running' state variable.
 func (c *Cron) run() {
 	// Figure out the next activation times for each entry.
-	now := time.Now().In(c.location)
+	now := c.now()
 	for _, entry := range c.entries {
 		entry.Next = entry.Schedule.Next(now)
 	}
@@ -178,22 +178,21 @@ func (c *Cron) run() {
 		// Determine the next entry to run.
 		sort.Sort(byTime(c.entries))
 
-		var effective time.Time
+		var timer *time.Timer
 		if len(c.entries) == 0 || c.entries[0].Next.IsZero() {
 			// If there are no entries yet, just sleep - it still handles new entries
 			// and stop requests.
-			effective = now.AddDate(10, 0, 0)
+			timer = time.NewTimer(100000 * time.Hour)
 		} else {
-			effective = c.entries[0].Next
+			timer = time.NewTimer(c.entries[0].Next.Sub(now))
 		}
 
-		timer := time.NewTimer(effective.Sub(now))
 		select {
 		case now = <-timer.C:
 			now = now.In(c.location)
-			// Run every entry whose next time was this effective time.
+			// Run every entry whose next time was less than now
 			for _, e := range c.entries {
-				if e.Next != effective {
+				if e.Next.After(now) || e.Next.IsZero() {
 					break
 				}
 				go c.runWithRecovery(e.Job)
@@ -251,3 +250,8 @@ func (c *Cron) entrySnapshot() []*Entry {
 	}
 	return entries
 }
+
+// now returns current time in c location
+func (c *Cron) now() time.Time {
+	return time.Now().In(c.location)
+}

+ 20 - 0
cron_test.go

@@ -316,6 +316,26 @@ func TestJob(t *testing.T) {
 	}
 }
 
+type ZeroSchedule struct{}
+
+func (*ZeroSchedule) Next(time.Time) time.Time {
+	return time.Time{}
+}
+
+// Tests that job without time does not run
+func TestJobWithZeroTimeDoesNotRun(t *testing.T) {
+	cron := New()
+	calls := 0
+	cron.AddFunc("* * * * * *", func() { calls += 1 })
+	cron.Schedule(new(ZeroSchedule), FuncJob(func() { t.Error("expected zero task will not run") }))
+	cron.Start()
+	defer cron.Stop()
+	<-time.After(OneSecond)
+	if calls != 1 {
+		t.Errorf("called %d times, expected 1\n", calls)
+	}
+}
+
 func wait(wg *sync.WaitGroup) chan bool {
 	ch := make(chan bool)
 	go func() {