Documentation ¶
Index ¶
- Constants
- Variables
- type AtTime
- type AtTimes
- type DaysOfTheMonth
- type Elector
- type EventListener
- func AfterJobRuns(eventListenerFunc func(jobID uuid.UUID, jobName string)) EventListener
- func AfterJobRunsWithError(eventListenerFunc func(jobID uuid.UUID, jobName string, err error)) EventListener
- func AfterJobRunsWithPanic(eventListenerFunc func(jobID uuid.UUID, jobName string, recoverData any)) EventListener
- func AfterLockError(eventListenerFunc func(jobID uuid.UUID, jobName string, err error)) EventListener
- func BeforeJobRuns(eventListenerFunc func(jobID uuid.UUID, jobName string)) EventListener
- type Job
- type JobDefinition
- func CronJob(crontab string, withSeconds bool) JobDefinition
- func DailyJob(interval uint, atTimes AtTimes) JobDefinition
- func DurationJob(duration time.Duration) JobDefinition
- func DurationRandomJob(minDuration, maxDuration time.Duration) JobDefinition
- func MonthlyJob(interval uint, daysOfTheMonth DaysOfTheMonth, atTimes AtTimes) JobDefinition
- func OneTimeJob(startAt OneTimeJobStartAtOption) JobDefinition
- func WeeklyJob(interval uint, daysOfTheWeek Weekdays, atTimes AtTimes) JobDefinition
- type JobOption
- func WithDistributedJobLocker(locker Locker) JobOption
- func WithEventListeners(eventListeners ...EventListener) JobOption
- func WithIdentifier(id uuid.UUID) JobOption
- func WithLimitedRuns(limit uint) JobOption
- func WithName(name string) JobOption
- func WithSingletonMode(mode LimitMode) JobOption
- func WithStartAt(option StartAtOption) JobOption
- func WithStopAt(option StopAtOption) JobOption
- func WithTags(tags ...string) JobOption
- type JobStatus
- type LimitMode
- type Lock
- type Locker
- type LogLevel
- type Logger
- type Monitor
- type OneTimeJobStartAtOption
- type Scheduler
- type SchedulerOption
- func WithClock(clock clockwork.Clock) SchedulerOption
- func WithDistributedElector(elector Elector) SchedulerOption
- func WithDistributedLocker(locker Locker) SchedulerOption
- func WithGlobalJobOptions(jobOptions ...JobOption) SchedulerOption
- func WithLimitConcurrentJobs(limit uint, mode LimitMode) SchedulerOption
- func WithLocation(location *time.Location) SchedulerOption
- func WithLogger(logger Logger) SchedulerOption
- func WithMonitor(monitor Monitor) SchedulerOption
- func WithStopTimeout(timeout time.Duration) SchedulerOption
- type StartAtOption
- type StopAtOption
- type Task
- type Weekdays
Examples ¶
- AfterJobRuns
- AfterJobRunsWithError
- AfterLockError
- BeforeJobRuns
- CronJob
- DailyJob
- DurationJob
- DurationRandomJob
- Job (Id)
- Job (LastRun)
- Job (Name)
- Job (NextRun)
- Job (NextRuns)
- Job (RunNow)
- Job (Tags)
- MonthlyJob
- NewScheduler
- OneTimeJob
- Scheduler (Jobs)
- Scheduler (NewJob)
- Scheduler (RemoveByTags)
- Scheduler (RemoveJob)
- Scheduler (Shutdown)
- Scheduler (Start)
- Scheduler (StopJobs)
- Scheduler (Update)
- WeeklyJob
- WithClock
- WithDistributedElector
- WithDistributedLocker
- WithEventListeners
- WithGlobalJobOptions
- WithIdentifier
- WithLimitConcurrentJobs
- WithLimitedRuns
- WithLocation
- WithLogger
- WithMonitor
- WithName
- WithSingletonMode
- WithStartAt
- WithStopTimeout
- WithTags
Constants ¶
const ( // LimitModeReschedule causes jobs reaching the limit set in // WithLimitConcurrentJobs or WithSingletonMode to be skipped // and rescheduled for the next run time rather than being // queued up to wait. LimitModeReschedule = 1 // LimitModeWait causes jobs reaching the limit set in // WithLimitConcurrentJobs or WithSingletonMode to wait // in a queue until a slot becomes available to run. // // Note: this mode can produce unpredictable results as // job execution order isn't guaranteed. For example, a job that // executes frequently may pile up in the wait queue and be executed // many times back to back when the queue opens. // // Warning: do not use this mode if your jobs will continue to stack // up beyond the ability of the limit workers to keep up. An example of // what NOT to do: // // s, _ := gocron.NewScheduler(gocron.WithLimitConcurrentJobs) // s.NewJob( // gocron.DurationJob( // time.Second, // Task{ // Function: func() { // time.Sleep(10 * time.Second) // }, // }, // ), // ) LimitModeWait = 2 )
Variables ¶
var ( ErrCronJobInvalid = fmt.Errorf("gocron: CronJob: invalid crontab") ErrCronJobParse = fmt.Errorf("gocron: CronJob: crontab parse failure") ErrDailyJobAtTimeNil = fmt.Errorf("gocron: DailyJob: atTime within atTimes must not be nil") ErrDailyJobAtTimesNil = fmt.Errorf("gocron: DailyJob: atTimes must not be nil") ErrDailyJobHours = fmt.Errorf("gocron: DailyJob: atTimes hours must be between 0 and 23 inclusive") ErrDailyJobMinutesSeconds = fmt.Errorf("gocron: DailyJob: atTimes minutes and seconds must be between 0 and 59 inclusive") ErrDurationJobIntervalZero = fmt.Errorf("gocron: DurationJob: time interval is 0") ErrDurationRandomJobMinMax = fmt.Errorf("gocron: DurationRandomJob: minimum duration must be less than maximum duration") ErrEventListenerFuncNil = fmt.Errorf("gocron: eventListenerFunc must not be nil") ErrJobNotFound = fmt.Errorf("gocron: job not found") ErrJobRunNowFailed = fmt.Errorf("gocron: Job: RunNow: scheduler unreachable") ErrMonthlyJobDays = fmt.Errorf("gocron: MonthlyJob: daysOfTheMonth must be between 31 and -31 inclusive, and not 0") ErrMonthlyJobAtTimeNil = fmt.Errorf("gocron: MonthlyJob: atTime within atTimes must not be nil") ErrMonthlyJobAtTimesNil = fmt.Errorf("gocron: MonthlyJob: atTimes must not be nil") ErrMonthlyJobDaysNil = fmt.Errorf("gocron: MonthlyJob: daysOfTheMonth must not be nil") ErrMonthlyJobHours = fmt.Errorf("gocron: MonthlyJob: atTimes hours must be between 0 and 23 inclusive") ErrMonthlyJobMinutesSeconds = fmt.Errorf("gocron: MonthlyJob: atTimes minutes and seconds must be between 0 and 59 inclusive") ErrNewJobTaskNil = fmt.Errorf("gocron: NewJob: Task must not be nil") ErrNewJobTaskNotFunc = fmt.Errorf("gocron: NewJob: Task.Function must be of kind reflect.Func") ErrNewJobWrongNumberOfParameters = fmt.Errorf("gocron: NewJob: Number of provided parameters does not match expected") ErrNewJobWrongTypeOfParameters = fmt.Errorf("gocron: NewJob: Type of provided parameters does not match expected") ErrOneTimeJobStartDateTimePast = fmt.Errorf("gocron: OneTimeJob: start must not be in the past") ErrStopExecutorTimedOut = fmt.Errorf("gocron: timed out waiting for executor to stop") ErrStopJobsTimedOut = fmt.Errorf("gocron: timed out waiting for jobs to finish") ErrStopSchedulerTimedOut = fmt.Errorf("gocron: timed out waiting for scheduler to stop") ErrWeeklyJobAtTimeNil = fmt.Errorf("gocron: WeeklyJob: atTime within atTimes must not be nil") ErrWeeklyJobAtTimesNil = fmt.Errorf("gocron: WeeklyJob: atTimes must not be nil") ErrWeeklyJobDaysOfTheWeekNil = fmt.Errorf("gocron: WeeklyJob: daysOfTheWeek must not be nil") ErrWeeklyJobHours = fmt.Errorf("gocron: WeeklyJob: atTimes hours must be between 0 and 23 inclusive") ErrWeeklyJobMinutesSeconds = fmt.Errorf("gocron: WeeklyJob: atTimes minutes and seconds must be between 0 and 59 inclusive") ErrPanicRecovered = fmt.Errorf("gocron: panic recovered") ErrWithClockNil = fmt.Errorf("gocron: WithClock: clock must not be nil") ErrWithDistributedElectorNil = fmt.Errorf("gocron: WithDistributedElector: elector must not be nil") ErrWithDistributedLockerNil = fmt.Errorf("gocron: WithDistributedLocker: locker must not be nil") ErrWithDistributedJobLockerNil = fmt.Errorf("gocron: WithDistributedJobLocker: locker must not be nil") ErrWithIdentifierNil = fmt.Errorf("gocron: WithIdentifier: identifier must not be nil") ErrWithLimitConcurrentJobsZero = fmt.Errorf("gocron: WithLimitConcurrentJobs: limit must be greater than 0") ErrWithLocationNil = fmt.Errorf("gocron: WithLocation: location must not be nil") ErrWithLoggerNil = fmt.Errorf("gocron: WithLogger: logger must not be nil") ErrWithMonitorNil = fmt.Errorf("gocron: WithMonitor: monitor must not be nil") ErrWithNameEmpty = fmt.Errorf("gocron: WithName: name must not be empty") ErrWithStartDateTimePast = fmt.Errorf("gocron: WithStartDateTime: start must not be in the past") ErrWithStopDateTimePast = fmt.Errorf("gocron: WithStopDateTime: end must not be in the past") ErrStartTimeLaterThanEndTime = fmt.Errorf("gocron: WithStartDateTime: start must not be later than end") ErrStopTimeEarlierThanStartTime = fmt.Errorf("gocron: WithStopDateTime: end must not be earlier than start") ErrWithStopTimeoutZeroOrNegative = fmt.Errorf("gocron: WithStopTimeout: timeout must be greater than 0") )
Public error definitions
Functions ¶
This section is empty.
Types ¶
type AtTimes ¶
type AtTimes func() []AtTime
AtTimes define a list of AtTime
func NewAtTimes ¶
NewAtTimes provide the hours, minutes and seconds at which the job should be run
type DaysOfTheMonth ¶
type DaysOfTheMonth func() days
DaysOfTheMonth defines a function that returns a list of days.
func NewDaysOfTheMonth ¶
func NewDaysOfTheMonth(day int, moreDays ...int) DaysOfTheMonth
NewDaysOfTheMonth provide the days of the month the job should run. The days can be positive 1 to 31 and/or negative -31 to -1. Negative values count backwards from the end of the month. For example: -1 == the last day of the month.
-5 == 5 days before the end of the month.
type Elector ¶
type Elector interface { // IsLeader should return nil if the job should be scheduled by the instance // making the request and an error if the job should not be scheduled. IsLeader(context.Context) error }
Elector determines the leader from instances asking to be the leader. Only the leader runs jobs. If the leader goes down, a new leader will be elected.
type EventListener ¶
type EventListener func(*internalJob) error
EventListener defines the constructor for event listeners that can be used to listen for job events.
func AfterJobRuns ¶
func AfterJobRuns(eventListenerFunc func(jobID uuid.UUID, jobName string)) EventListener
AfterJobRuns is used to listen for when a job has run without an error, and then run the provided function.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), WithEventListeners( AfterJobRuns( func(jobID uuid.UUID, jobName string) { // do something after the job completes }, ), ), )
Output:
func AfterJobRunsWithError ¶
func AfterJobRunsWithError(eventListenerFunc func(jobID uuid.UUID, jobName string, err error)) EventListener
AfterJobRunsWithError is used to listen for when a job has run and returned an error, and then run the provided function.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), WithEventListeners( AfterJobRunsWithError( func(jobID uuid.UUID, jobName string, err error) { // do something when the job returns an error }, ), ), )
Output:
func AfterJobRunsWithPanic ¶
func AfterJobRunsWithPanic(eventListenerFunc func(jobID uuid.UUID, jobName string, recoverData any)) EventListener
AfterJobRunsWithPanic is used to listen for when a job has run and returned panicked recover data, and then run the provided function.
func AfterLockError ¶
func AfterLockError(eventListenerFunc func(jobID uuid.UUID, jobName string, err error)) EventListener
AfterLockError is used to when the distributed locker returns an error and then run the provided function.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), WithDistributedJobLocker(&errorLocker{}), WithEventListeners( AfterLockError( func(jobID uuid.UUID, jobName string, err error) { // do something immediately before the job is run }, ), ), )
Output:
func BeforeJobRuns ¶
func BeforeJobRuns(eventListenerFunc func(jobID uuid.UUID, jobName string)) EventListener
BeforeJobRuns is used to listen for when a job is about to run and then run the provided function.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), WithEventListeners( BeforeJobRuns( func(jobID uuid.UUID, jobName string) { // do something immediately before the job is run }, ), ), )
Output:
type Job ¶
type Job interface { // ID returns the job's unique identifier. ID() uuid.UUID // LastRun returns the time of the job's last run LastRun() (time.Time, error) // Name returns the name defined on the job. Name() string // NextRun returns the time of the job's next scheduled run. NextRun() (time.Time, error) // NextRuns returns the requested number of calculated next run values. NextRuns(int) ([]time.Time, error) // RunNow runs the job once, now. This does not alter // the existing run schedule, and will respect all job // and scheduler limits. This means that running a job now may // cause the job's regular interval to be rescheduled due to // the instance being run by RunNow blocking your run limit. RunNow() error // Tags returns the job's string tags. Tags() []string }
Job provides the available methods on the job available to the caller.
Example (Id) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), ) fmt.Println(j.ID())
Output:
Example (LastRun) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), ) fmt.Println(j.LastRun())
Output:
Example (Name) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), WithName("foobar"), ) fmt.Println(j.Name())
Output: foobar
Example (NextRun) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), ) nextRun, _ := j.NextRun() fmt.Println(nextRun)
Output:
Example (NextRuns) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), ) nextRuns, _ := j.NextRuns(5) fmt.Println(nextRuns)
Output:
Example (RunNow) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( MonthlyJob( 1, NewDaysOfTheMonth(3, -5, -1), NewAtTimes( NewAtTime(10, 30, 0), NewAtTime(11, 15, 0), ), ), NewTask( func() {}, ), ) s.Start() // Runs the job one time now, without impacting the schedule _ = j.RunNow()
Output:
Example (Tags) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), WithTags("foo", "bar"), ) fmt.Println(j.Tags())
Output: [foo bar]
type JobDefinition ¶
type JobDefinition interface {
// contains filtered or unexported methods
}
JobDefinition defines the interface that must be implemented to create a job from the definition.
func CronJob ¶
func CronJob(crontab string, withSeconds bool) JobDefinition
CronJob defines a new job using the crontab syntax: `* * * * *`. An optional 6th field can be used at the beginning if withSeconds is set to true: `* * * * * *`. The timezone can be set on the Scheduler using WithLocation, or in the crontab in the form `TZ=America/Chicago * * * * *` or `CRON_TZ=America/Chicago * * * * *`
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( CronJob( // standard cron tab parsing "1 * * * *", false, ), NewTask( func() {}, ), ) _, _ = s.NewJob( CronJob( // optionally include seconds as the first field "* 1 * * * *", true, ), NewTask( func() {}, ), )
Output:
func DailyJob ¶
func DailyJob(interval uint, atTimes AtTimes) JobDefinition
DailyJob runs the job on the interval of days, and at the set times. By default, the job will start the next available day, considering the last run to be now, and the time and day based on the interval and times you input. This means, if you select an interval greater than 1, your job by default will run X (interval) days from now if there are no atTimes left in the current day. You can use WithStartAt to tell the scheduler to start the job sooner.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DailyJob( 1, NewAtTimes( NewAtTime(10, 30, 0), NewAtTime(14, 0, 0), ), ), NewTask( func(a, b string) {}, "a", "b", ), )
Output:
func DurationJob ¶
func DurationJob(duration time.Duration) JobDefinition
DurationJob defines a new job using time.Duration for the interval.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( time.Second*5, ), NewTask( func() {}, ), )
Output:
func DurationRandomJob ¶
func DurationRandomJob(minDuration, maxDuration time.Duration) JobDefinition
DurationRandomJob defines a new job that runs on a random interval between the min and max duration values provided.
To achieve a similar behavior as tools that use a splay/jitter technique consider the median value as the baseline and the difference between the max-median or median-min as the splay/jitter.
For example, if you want a job to run every 5 minutes, but want to add up to 1 min of jitter to the interval, you could use DurationRandomJob(4*time.Minute, 6*time.Minute)
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationRandomJob( time.Second, 5*time.Second, ), NewTask( func() {}, ), )
Output:
func MonthlyJob ¶
func MonthlyJob(interval uint, daysOfTheMonth DaysOfTheMonth, atTimes AtTimes) JobDefinition
MonthlyJob runs the job on the interval of months, on the specific days of the month specified, and at the set times. Days of the month can be 1 to 31 or negative (-1 to -31), which count backwards from the end of the month. E.g. -1 is the last day of the month.
If a day of the month is selected that does not exist in all months (e.g. 31st) any month that does not have that day will be skipped.
By default, the job will start the next available day, considering the last run to be now, and the time and month based on the interval, days and times you input. This means, if you select an interval greater than 1, your job by default will run X (interval) months from now if there are no daysOfTheMonth left in the current month. You can use WithStartAt to tell the scheduler to start the job sooner.
Carefully consider your configuration!
- For example: an interval of 2 months on the 31st of each month, starting 12/31 would skip Feb, April, June, and next run would be in August.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( MonthlyJob( 1, NewDaysOfTheMonth(3, -5, -1), NewAtTimes( NewAtTime(10, 30, 0), NewAtTime(11, 15, 0), ), ), NewTask( func() {}, ), )
Output:
func OneTimeJob ¶
func OneTimeJob(startAt OneTimeJobStartAtOption) JobDefinition
OneTimeJob is to run a job once at a specified time and not on any regular schedule.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() // run a job once, immediately _, _ = s.NewJob( OneTimeJob( OneTimeJobStartImmediately(), ), NewTask( func() {}, ), ) // run a job once in 10 seconds _, _ = s.NewJob( OneTimeJob( OneTimeJobStartDateTime(time.Now().Add(10*time.Second)), ), NewTask( func() {}, ), ) // run job twice - once in 10 seconds and once in 55 minutes n := time.Now() _, _ = s.NewJob( OneTimeJob( OneTimeJobStartDateTimes( n.Add(10*time.Second), n.Add(55*time.Minute), ), ), NewTask(func() {}), ) s.Start()
Output:
func WeeklyJob ¶
func WeeklyJob(interval uint, daysOfTheWeek Weekdays, atTimes AtTimes) JobDefinition
WeeklyJob runs the job on the interval of weeks, on the specific days of the week specified, and at the set times.
By default, the job will start the next available day, considering the last run to be now, and the time and day based on the interval, days and times you input. This means, if you select an interval greater than 1, your job by default will run X (interval) weeks from now if there are no daysOfTheWeek left in the current week. You can use WithStartAt to tell the scheduler to start the job sooner.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( WeeklyJob( 2, NewWeekdays(time.Tuesday, time.Wednesday, time.Saturday), NewAtTimes( NewAtTime(1, 30, 0), NewAtTime(12, 0, 30), ), ), NewTask( func() {}, ), )
Output:
type JobOption ¶
JobOption defines the constructor for job options.
func WithDistributedJobLocker ¶
WithDistributedJobLocker sets the locker to be used by multiple Scheduler instances to ensure that only one instance of each job is run.
func WithEventListeners ¶
func WithEventListeners(eventListeners ...EventListener) JobOption
WithEventListeners sets the event listeners that should be run for the job.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), WithEventListeners( AfterJobRuns( func(jobID uuid.UUID, jobName string) { // do something after the job completes }, ), AfterJobRunsWithError( func(jobID uuid.UUID, jobName string, err error) { // do something when the job returns an error }, ), BeforeJobRuns( func(jobID uuid.UUID, jobName string) { // do something immediately before the job is run }, ), ), )
Output:
func WithIdentifier ¶
WithIdentifier sets the identifier for the job. The identifier is used to uniquely identify the job and is used for logging and metrics.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func(one string, two int) { fmt.Printf("%s, %d", one, two) }, "one", 2, ), WithIdentifier(uuid.MustParse("87b95dfc-3e71-11ef-9454-0242ac120002")), ) fmt.Println(j.ID())
Output: 87b95dfc-3e71-11ef-9454-0242ac120002
func WithLimitedRuns ¶
WithLimitedRuns limits the number of executions of this job to n. Upon reaching the limit, the job is removed from the scheduler.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( time.Millisecond, ), NewTask( func(one string, two int) { fmt.Printf("%s, %d\n", one, two) }, "one", 2, ), WithLimitedRuns(1), ) s.Start() time.Sleep(100 * time.Millisecond) _ = s.StopJobs() fmt.Printf("no jobs in scheduler: %v\n", s.Jobs())
Output: one, 2 no jobs in scheduler: []
func WithName ¶
WithName sets the name of the job. Name provides a human-readable identifier for the job.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func(one string, two int) { fmt.Printf("%s, %d", one, two) }, "one", 2, ), WithName("job 1"), ) fmt.Println(j.Name())
Output: job 1
func WithSingletonMode ¶
WithSingletonMode keeps the job from running again if it is already running. This is useful for jobs that should not overlap, and that occasionally (but not consistently) run longer than the interval between job runs.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( time.Second, ), NewTask( func() { // this job will skip half it's executions // and effectively run every 2 seconds time.Sleep(1500 * time.Second) }, ), WithSingletonMode(LimitModeReschedule), )
Output:
func WithStartAt ¶
func WithStartAt(option StartAtOption) JobOption
WithStartAt sets the option for starting the job at a specific datetime.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() start := time.Date(9999, 9, 9, 9, 9, 9, 9, time.UTC) j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func(one string, two int) { fmt.Printf("%s, %d", one, two) }, "one", 2, ), WithStartAt( WithStartDateTime(start), ), ) s.Start() next, _ := j.NextRun() fmt.Println(next) _ = s.StopJobs()
Output: 9999-09-09 09:09:09.000000009 +0000 UTC
func WithStopAt ¶
func WithStopAt(option StopAtOption) JobOption
WithStopAt sets the option for stopping the job from running after the specified time.
func WithTags ¶
WithTags sets the tags for the job. Tags provide a way to identify jobs by a set of tags and remove multiple jobs by tag.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func(one string, two int) { fmt.Printf("%s, %d", one, two) }, "one", 2, ), WithTags("tag1", "tag2", "tag3"), ) fmt.Println(j.Tags())
Output: [tag1 tag2 tag3]
type JobStatus ¶
type JobStatus string
JobStatus is the status of job run that should be collected with the metric.
type LimitMode ¶
type LimitMode int
LimitMode defines the modes used for handling jobs that reach the limit provided in WithLimitConcurrentJobs
type Lock ¶
Lock represents an obtained lock. The lock is released after the execution of the job by the scheduler.
type Locker ¶
type Locker interface { // Lock if an error is returned by lock, the job will not be scheduled. Lock(ctx context.Context, key string) (Lock, error) }
Locker represents the required interface to lock jobs when running multiple schedulers. The lock is held for the duration of the job's run, and it is expected that the locker implementation handles time splay between schedulers. The lock key passed is the job's name - which, if not set, defaults to the go function's name, e.g. "pkg.myJob" for func myJob() {} in pkg
type LogLevel ¶
type LogLevel int
LogLevel is the level of logging that should be logged when using the basic NewLogger.
type Logger ¶
type Logger interface { Debug(msg string, args ...any) Error(msg string, args ...any) Info(msg string, args ...any) Warn(msg string, args ...any) }
Logger is the interface that wraps the basic logging methods used by gocron. The methods are modeled after the standard library slog package. The default logger is a no-op logger. To enable logging, use one of the provided New*Logger functions or implement your own Logger. The actual level of Log that is logged is handled by the implementation.
type Monitor ¶
type Monitor interface { // IncrementJob will provide details about the job and expects the underlying implementation // to handle instantiating and incrementing a value IncrementJob(id uuid.UUID, name string, tags []string, status JobStatus) // RecordJobTiming will provide details about the job and the timing and expects the underlying implementation // to handle instantiating and recording the value RecordJobTiming(startTime, endTime time.Time, id uuid.UUID, name string, tags []string) }
Monitor represents the interface to collect jobs metrics.
type OneTimeJobStartAtOption ¶
OneTimeJobStartAtOption defines when the one time job is run
func OneTimeJobStartDateTime ¶
func OneTimeJobStartDateTime(start time.Time) OneTimeJobStartAtOption
OneTimeJobStartDateTime sets the date & time at which the job should run. This datetime must be in the future (according to the scheduler clock).
func OneTimeJobStartDateTimes ¶
func OneTimeJobStartDateTimes(times ...time.Time) OneTimeJobStartAtOption
OneTimeJobStartDateTimes sets the date & times at which the job should run. At least one of the date/times must be in the future (according to the scheduler clock).
func OneTimeJobStartImmediately ¶
func OneTimeJobStartImmediately() OneTimeJobStartAtOption
OneTimeJobStartImmediately tells the scheduler to run the one time job immediately.
type Scheduler ¶
type Scheduler interface { // Jobs returns all the jobs currently in the scheduler. Jobs() []Job // NewJob creates a new job in the Scheduler. The job is scheduled per the provided // definition when the Scheduler is started. If the Scheduler is already running // the job will be scheduled when the Scheduler is started. NewJob(JobDefinition, Task, ...JobOption) (Job, error) // RemoveByTags removes all jobs that have at least one of the provided tags. RemoveByTags(...string) // RemoveJob removes the job with the provided id. RemoveJob(uuid.UUID) error // Shutdown should be called when you no longer need // the Scheduler or Job's as the Scheduler cannot // be restarted after calling Shutdown. This is similar // to a Close or Cleanup method and is often deferred after // starting the scheduler. Shutdown() error // Start begins scheduling jobs for execution based // on each job's definition. Job's added to an already // running scheduler will be scheduled immediately based // on definition. Start is non-blocking. Start() // StopJobs stops the execution of all jobs in the scheduler. // This can be useful in situations where jobs need to be // paused globally and then restarted with Start(). StopJobs() error // Update replaces the existing Job's JobDefinition with the provided // JobDefinition. The Job's Job.ID() remains the same. Update(uuid.UUID, JobDefinition, Task, ...JobOption) (Job, error) // JobsWaitingInQueue number of jobs waiting in Queue in case of LimitModeWait // In case of LimitModeReschedule or no limit it will be always zero JobsWaitingInQueue() int }
Scheduler defines the interface for the Scheduler.
Example (Jobs) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( 10*time.Second, ), NewTask( func() {}, ), ) fmt.Println(len(s.Jobs()))
Output: 1
Example (NewJob) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, err := s.NewJob( DurationJob( 10*time.Second, ), NewTask( func() {}, ), ) if err != nil { panic(err) } fmt.Println(j.ID())
Output:
Example (RemoveByTags) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), WithTags("tag1"), ) _, _ = s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), WithTags("tag2"), ) fmt.Println(len(s.Jobs())) s.RemoveByTags("tag1", "tag2") fmt.Println(len(s.Jobs()))
Output: 2 0
Example (RemoveJob) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func() {}, ), ) fmt.Println(len(s.Jobs())) _ = s.RemoveJob(j.ID()) fmt.Println(len(s.Jobs()))
Output: 1 0
Example (Shutdown) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }()
Output:
Example (Start) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( CronJob( "* * * * *", false, ), NewTask( func() {}, ), ) s.Start()
Output:
Example (StopJobs) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() _, _ = s.NewJob( CronJob( "* * * * *", false, ), NewTask( func() {}, ), ) s.Start() _ = s.StopJobs()
Output:
Example (Update) ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() j, _ := s.NewJob( CronJob( "* * * * *", false, ), NewTask( func() {}, ), ) s.Start() // after some time, need to change the job j, _ = s.Update( j.ID(), DurationJob( 5*time.Second, ), NewTask( func() {}, ), )
Output:
func NewScheduler ¶
func NewScheduler(options ...SchedulerOption) (Scheduler, error)
NewScheduler creates a new Scheduler instance. The Scheduler is not started until Start() is called.
NewJob will add jobs to the Scheduler, but they will not be scheduled until Start() is called.
Example ¶
s, _ := NewScheduler() defer func() { _ = s.Shutdown() }() fmt.Println(s.Jobs())
Output:
type SchedulerOption ¶
type SchedulerOption func(*scheduler) error
SchedulerOption defines the function for setting options on the Scheduler.
func WithClock ¶
func WithClock(clock clockwork.Clock) SchedulerOption
WithClock sets the clock used by the Scheduler to the clock provided. See https://github.com/jonboulle/clockwork
Example ¶
fakeClock := clockwork.NewFakeClock() s, _ := NewScheduler( WithClock(fakeClock), ) var wg sync.WaitGroup wg.Add(1) _, _ = s.NewJob( DurationJob( time.Second*5, ), NewTask( func(one string, two int) { fmt.Printf("%s, %d\n", one, two) wg.Done() }, "one", 2, ), ) s.Start() fakeClock.BlockUntil(1) fakeClock.Advance(time.Second * 5) wg.Wait() _ = s.StopJobs()
Output: one, 2
func WithDistributedElector ¶
func WithDistributedElector(elector Elector) SchedulerOption
WithDistributedElector sets the elector to be used by multiple Scheduler instances to determine who should be the leader. Only the leader runs jobs, while non-leaders wait and continue to check if a new leader has been elected.
Example ¶
//var _ gocron.Elector = (*myElector)(nil) // //type myElector struct{} // //func (m myElector) IsLeader(_ context.Context) error { // return nil //} // //elector := &myElector{} // //_, _ = gocron.NewScheduler( // gocron.WithDistributedElector(elector), //)
Output:
func WithDistributedLocker ¶
func WithDistributedLocker(locker Locker) SchedulerOption
WithDistributedLocker sets the locker to be used by multiple Scheduler instances to ensure that only one instance of each job is run.
Example ¶
//var _ gocron.Locker = (*myLocker)(nil) // //type myLocker struct{} // //func (m myLocker) Lock(ctx context.Context, key string) (Lock, error) { // return &testLock, nil //} // //var _ Lock = (*testLock)(nil) // //type testLock struct { //} // //func (t testLock) Unlock(_ context.Context) error { // return nil //} // //locker := &myLocker{} // //_, _ = gocron.NewScheduler( // gocron.WithDistributedLocker(locker), //)
Output:
func WithGlobalJobOptions ¶
func WithGlobalJobOptions(jobOptions ...JobOption) SchedulerOption
WithGlobalJobOptions sets JobOption's that will be applied to all jobs added to the scheduler. JobOption's set on the job itself will override if the same JobOption is set globally.
Example ¶
s, _ := NewScheduler( WithGlobalJobOptions( WithTags("tag1", "tag2", "tag3"), ), ) j, _ := s.NewJob( DurationJob( time.Second, ), NewTask( func(one string, two int) { fmt.Printf("%s, %d", one, two) }, "one", 2, ), ) // The job will have the globally applied tags fmt.Println(j.Tags()) s2, _ := NewScheduler( WithGlobalJobOptions( WithTags("tag1", "tag2", "tag3"), ), ) j2, _ := s2.NewJob( DurationJob( time.Second, ), NewTask( func(one string, two int) { fmt.Printf("%s, %d", one, two) }, "one", 2, ), WithTags("tag4", "tag5", "tag6"), ) // The job will have the tags set specifically on the job // overriding those set globally by the scheduler fmt.Println(j2.Tags())
Output: [tag1 tag2 tag3] [tag4 tag5 tag6]
func WithLimitConcurrentJobs ¶
func WithLimitConcurrentJobs(limit uint, mode LimitMode) SchedulerOption
WithLimitConcurrentJobs sets the limit and mode to be used by the Scheduler for limiting the number of jobs that may be running at a given time.
Note: the limit mode selected for WithLimitConcurrentJobs takes initial precedence in the event you are also running a limit mode at the job level using WithSingletonMode.
Warning: a single time consuming job can dominate your limit in the event you are running both the scheduler limit WithLimitConcurrentJobs(1, LimitModeWait) and a job limit WithSingletonMode(LimitModeReschedule).
Example ¶
_, _ = NewScheduler( WithLimitConcurrentJobs( 1, LimitModeReschedule, ), )
Output:
func WithLocation ¶
func WithLocation(location *time.Location) SchedulerOption
WithLocation sets the location (i.e. timezone) that the scheduler should operate within. In many systems time.Local is UTC. Default: time.Local
Example ¶
location, _ := time.LoadLocation("Asia/Kolkata") _, _ = NewScheduler( WithLocation(location), )
Output:
func WithLogger ¶
func WithLogger(logger Logger) SchedulerOption
WithLogger sets the logger to be used by the Scheduler.
Example ¶
_, _ = NewScheduler( WithLogger( NewLogger(LogLevelDebug), ), )
Output:
func WithMonitor ¶
func WithMonitor(monitor Monitor) SchedulerOption
WithMonitor sets the metrics provider to be used by the Scheduler.
Example ¶
//type exampleMonitor struct { // mu sync.Mutex // counter map[string]int // time map[string][]time.Duration //} // //func newExampleMonitor() *exampleMonitor { // return &exampleMonitor{ // counter: make(map[string]int), // time: make(map[string][]time.Duration), //} //} // //func (t *exampleMonitor) IncrementJob(_ uuid.UUID, name string, _ []string, _ JobStatus) { // t.mu.Lock() // defer t.mu.Unlock() // _, ok := t.counter[name] // if !ok { // t.counter[name] = 0 // } // t.counter[name]++ //} // //func (t *exampleMonitor) RecordJobTiming(startTime, endTime time.Time, _ uuid.UUID, name string, _ []string) { // t.mu.Lock() // defer t.mu.Unlock() // _, ok := t.time[name] // if !ok { // t.time[name] = make([]time.Duration, 0) // } // t.time[name] = append(t.time[name], endTime.Sub(startTime)) //} // //monitor := newExampleMonitor() //s, _ := NewScheduler( // WithMonitor(monitor), //) //name := "example" //_, _ = s.NewJob( // DurationJob( // time.Second, // ), // NewTask( // func() { // time.Sleep(1 * time.Second) // }, // ), // WithName(name), // WithStartAt( // WithStartImmediately(), // ), //) //s.Start() //time.Sleep(5 * time.Second) //_ = s.Shutdown() // //fmt.Printf("Job %q total execute count: %d\n", name, monitor.counter[name]) //for i, val := range monitor.time[name] { // fmt.Printf("Job %q execute #%d elapsed %.4f seconds\n", name, i+1, val.Seconds()) //}
Output:
func WithStopTimeout ¶
func WithStopTimeout(timeout time.Duration) SchedulerOption
WithStopTimeout sets the amount of time the Scheduler should wait gracefully for jobs to complete before returning when StopJobs() or Shutdown() are called. Default: 10 * time.Second
Example ¶
_, _ = NewScheduler( WithStopTimeout(time.Second * 5), )
Output:
type StartAtOption ¶
StartAtOption defines options for starting the job
func WithStartDateTime ¶
func WithStartDateTime(start time.Time) StartAtOption
WithStartDateTime sets the first date & time at which the job should run. This datetime must be in the future.
func WithStartImmediately ¶
func WithStartImmediately() StartAtOption
WithStartImmediately tells the scheduler to run the job immediately regardless of the type or schedule of job. After this immediate run the job is scheduled from this time based on the job definition.
type StopAtOption ¶
StopAtOption defines options for stopping the job
func WithStopDateTime ¶
func WithStopDateTime(end time.Time) StopAtOption
WithStopDateTime sets the final date & time after which the job should stop. This must be in the future and should be after the startTime (if specified). The job's final run may be at the stop time, but not after.