// Entry consists of a schedule and the func to execute on that schedule. // 记录:包含了一个定时计划,以及这个计划要执行的函数 type Entry struct { // ID is the cron-assigned ID of this entry, which may be used to look up a // snapshot or remove it. // 记录id,方便后续用来对项目的定时、执行内容、状态控制 ID EntryID
// Schedule on which this job should be run. // 计划接口 Schedule Schedule
// Next time the job will run, or the zero time if Cron has not been // started or this entry's schedule is unsatisfiable //下次运行时间 Next time.Time
// Prev is the last time this job was run, or the zero time if never. //上一次运行时间 Prev time.Time
// WrappedJob is the thing to run when the Schedule is activated. // 类似于装饰器一样的任务触发装置 WrappedJob Job
// Job is the thing that was submitted to cron. // It is kept around so that user code that needs to get at the job later, // e.g. via Entries() can do so. // 真正要执行的任务 Job Job }
// Run the scheduler. this is private just due to the need to synchronize // access to the 'running' state variable. // 执行定时任务 // 执行调度器. // 该任务的执行是否私有完全由'running'变量是否具有同步权限决定 func(c *Cron) run() { // Figure out the next activation times for each entry. // 获取所有任务的下一次执行时间 now := c.now() for _, entry := range c.entries { entry.Next = entry.Schedule.Next(now) }
for { // Determine the next entry to run. // 根据时间顺序决定任务的执行顺序, 时间越大的越靠前 sort.Sort(byTime(c.entries))
var timer *time.Timer iflen(c.entries) == 0 || c.entries[0].Next.IsZero() { // If there are no entries yet, just sleep - it still handles new entries // and stop requests. // 若任务入口slice为空, 则调取器休眠, 在休眠期间, 它仍然可以处理新的任务入口slice和任务停止请求 timer = time.NewTimer(100000 * time.Hour) } else { timer = time.NewTimer(c.entries[0].Next.Sub(now)) }
for { select { case now = <-timer.C: // 执行当前任务 now = now.In(c.location) // Run every entry whose next time was less than now for _, e := range c.entries { if e.Next.After(now) || e.Next.IsZero() { break } go c.runWithRecovery(e.Job) e.Prev = e.Next e.Next = e.Schedule.Next(now) }
case newEntry := <-c.add: // 指向新的任务 timer.Stop() now = c.now() newEntry.Next = newEntry.Schedule.Next(now) c.entries = append(c.entries, newEntry)
case <-c.snapshot: // 获取快照 c.snapshot <- c.entrySnapshot() continue