job.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package gocron
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. )
  7. // Job struct stores the information necessary to run a Job
  8. type Job struct {
  9. sync.RWMutex
  10. interval uint64 // pause interval * unit between runs
  11. unit timeUnit // time units, ,e.g. 'minutes', 'hours'...
  12. startsImmediately bool // if the Job should run upon scheduler start
  13. jobFunc string // the Job jobFunc to run, func[jobFunc]
  14. atTime time.Duration // optional time at which this Job runs
  15. err error // error related to Job
  16. lastRun time.Time // datetime of last run
  17. nextRun time.Time // datetime of next run
  18. scheduledWeekday *time.Weekday // Specific day of the week to start on
  19. dayOfTheMonth int // Specific day of the month to run the job
  20. funcs map[string]interface{} // Map for the function task store
  21. fparams map[string][]interface{} // Map for function and params of function
  22. tags []string // allow the user to tag Jobs with certain labels
  23. runConfig runConfig // configuration for how many times to run the job
  24. runCount int // number of time the job ran
  25. }
  26. type runConfig struct {
  27. finiteRuns bool
  28. maxRuns int
  29. }
  30. // NewJob creates a new Job with the provided interval
  31. func NewJob(interval uint64) *Job {
  32. return &Job{
  33. interval: interval,
  34. lastRun: time.Time{},
  35. nextRun: time.Time{},
  36. funcs: make(map[string]interface{}),
  37. fparams: make(map[string][]interface{}),
  38. tags: []string{},
  39. }
  40. }
  41. // Run the Job and immediately reschedule it
  42. func (j *Job) run() {
  43. j.Lock()
  44. defer j.Unlock()
  45. callJobFuncWithParams(j.funcs[j.jobFunc], j.fparams[j.jobFunc])
  46. j.runCount++
  47. }
  48. func (j *Job) neverRan() bool {
  49. return j.lastRun.IsZero()
  50. }
  51. // Err returns an error if one ocurred while creating the Job
  52. func (j *Job) Err() error {
  53. return j.err
  54. }
  55. // Tag allows you to add arbitrary labels to a Job that do not
  56. // impact the functionality of the Job
  57. func (j *Job) Tag(t string, others ...string) {
  58. j.tags = append(j.tags, t)
  59. for _, tag := range others {
  60. j.tags = append(j.tags, tag)
  61. }
  62. }
  63. // Untag removes a tag from a Job
  64. func (j *Job) Untag(t string) {
  65. newTags := []string{}
  66. for _, tag := range j.tags {
  67. if t != tag {
  68. newTags = append(newTags, tag)
  69. }
  70. }
  71. j.tags = newTags
  72. }
  73. // Tags returns the tags attached to the Job
  74. func (j *Job) Tags() []string {
  75. return j.tags
  76. }
  77. // ScheduledTime returns the time of the Job's next scheduled run
  78. func (j *Job) ScheduledTime() time.Time {
  79. return j.nextRun
  80. }
  81. // ScheduledAtTime returns the specific time of day the Job will run at
  82. func (j *Job) ScheduledAtTime() string {
  83. return fmt.Sprintf("%d:%d", j.atTime/time.Hour, (j.atTime%time.Hour)/time.Minute)
  84. }
  85. // Weekday returns which day of the week the Job will run on and
  86. // will return an error if the Job is not scheduled weekly
  87. func (j *Job) Weekday() (time.Weekday, error) {
  88. if j.scheduledWeekday == nil {
  89. return time.Sunday, ErrNotScheduledWeekday
  90. }
  91. return *j.scheduledWeekday, nil
  92. }
  93. // LimitRunsTo limits the number of executions of this
  94. // job to n. However, the job will still remain in the
  95. // scheduler
  96. func (j *Job) LimitRunsTo(n int) {
  97. j.runConfig = runConfig{
  98. finiteRuns: true,
  99. maxRuns: n,
  100. }
  101. }
  102. // shouldRun eveluates if this job should run again
  103. // based on the runConfig
  104. func (j *Job) shouldRun() bool {
  105. return !j.runConfig.finiteRuns || j.runCount < j.runConfig.maxRuns
  106. }