golang rofig/cron

https://github.com/robfig/cron

Cron entries are stored in an array, sorted by their next activation time. Cron sleeps until the next job is due to be run.
Upon waking:

  • it runs each entry that is active on that second
  • it calculates the next run times for the jobs that were run
  • it re-sorts the array of entries by next activation time.
  • it goes to sleep until the soonest job.

Example

content_copy
c := cron.New()
c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") })
c.AddFunc("@hourly",      func() { fmt.Println("Every hour") })
c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") })
c.Start()
..
// Funcs are invoked in their own goroutine, asynchronously.
...
// Funcs may also be added to a running Cron
c.AddFunc("@daily", func() { fmt.Println("Every day") })
..
// Inspect the cron job entries' next and previous run times.
inspect(c.Entries())
..
c.Stop()  // Stop the scheduler (does not stop any jobs already running).

Cron definition

content_copy
type Cron struct {
	entries   []*Entry // cron entries
	chain     Chain //sequence of JobWrappers that decorates submitted jobs, e.g. logging, sync
	stop      chan struct{} // channel signaling stop
	add       chan *Entry // channnel signaling new entry, calculate new schedule then append to entry
	remove    chan EntryID // channel signaling remove entry (contruct new entry list without that entry)
	snapshot  chan chan []Entry // channel signaling return existing entries
	running   bool // determine is cron is running
	logger    Logger // normal and discard logger
	runningMu sync.Mutex // a mutual exclusion lock. The zero value for a Mutex is an unlocked mutex.
	location  *time.Location // time.Now().In(c.location)
	parser    ScheduleParser // Parse to format 		Second:   second,
                                                  Minute:   minute,
                                                  Hour:     hour,
                                                  Dom:      dayofmonth,
                                                  Month:    month,
                                                  Dow:      dayofweek,
                                                  Location: loc,
	nextID    EntryID //
	jobWaiter sync.WaitGroup // A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished.
}

Plain text

content_copy
Start
- mutex lock running
- return if already running
- set running to true
- go c.run()
  - Log start
  - Loop entries calculate Next schedule time
  - while
    - sort entries, earliest first
    - timer long hours (simulate sleep) if no entry
      timer duration till next execute
    - while
      - case timer done
          - logger.info wake
          - loop entries
            - break if entries.Next > now
            - start job
            - calculate new Next
            - logger.info done
        case new entry (channel add)
          - stop timer
          - calculate next schedule for new entry
          - add new entry
        case snapshot
          - send current entries to replyChannel
        case stop (channel stop)
          - timer stop
          - log stop
        case remove (channel remove)
          - timer stop
          - remove entry (new list without entered entry id)
content_copy

Comments