gocron

package module
v2.0.0-...-8b0aba8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 17, 2023 License: MIT Imports: 17 Imported by: 0

README

gocron: A Golang Job Scheduling Package

CI State Go Report Card Go Doc

gocron is a job scheduling package which lets you run Go functions at pre-determined intervals.

If you want to chat, you can find us on Slack at

Quick Start

go get github.com/go-co-op/gocron/v2
package main

import (
	"fmt"
	"time"

	"github.com/go-co-op/gocron/v2"
)

func main() {
	// create a scheduler
	s, err := gocron.NewScheduler()
	if err != nil {
		// handle error
	}

	// add a job to the scheduler
	j, err := s.NewJob(
		gocron.DurationJob(
			10*time.Second,
		),
		gocron.NewTask(
			func(a string, b int) {
				// do things
            },
			"hello",
			1,
		),
	)
	if err != nil {
		// handle error
	}
	// each job has a unique id
	fmt.Println(j.ID())

	// start the scheduler
	s.Start()

	// when you're done, shut it down
	err = s.Shutdown()
	if err != nil {
		// handle error
	}
}

Concepts

  • Job: The job encapsulates a "task", which is made up of a go function and any function parameters. The Job then provides the scheduler with the time the job should next be scheduled to run.
  • Scheduler: The scheduler keeps track of all the jobs and sends each job to the executor when it is ready to be run.
  • Executor: The executor calls the job's task and manages the complexities of different job execution timing requirements (e.g. singletons that shouldn't overrun each other, limiting the max number of jobs running)

Features

Job types

Jobs can be run at various intervals.

  • Duration: Jobs can be run at a fixed time.Duration.
  • Random duration: Jobs can be run at a random time.Duration between a min and max.
  • Cron: Jobs can be run using a crontab.
  • Daily: Jobs can be run every x days at specific times.
  • Weekly: Jobs can be run every x weeks on specific days of the week and at specific times.
  • Monthly: Jobs can be run every x months on specific days of the month and at specific times.
Concurrency Limits

Jobs can be limited individually or across the entire scheduler.

  • Per job limiting with singleton mode: Jobs can be limited to a single concurrent execution that either reschedules (skips overlapping executions) or queues (waits for the previous execution to finish).
  • Per scheduler limiting with limit mode: Jobs can be limited to a certain number of concurrent executions across the entire scheduler using either reschedule (skip when the limit is met) or queue (jobs are added to a queue to wait for the limit to be available).
  • Note: A scheduler limit and a job limit can both be enabled.
Distributed instances of gocron

Multiple instances of gocron can be run.

  • Elector: An elector can be used to elect a single instance of gocron to run as the primary with the other instances checking to see if a new leader needs to be elected.
  • Implementations: go-co-op electors
  • Locker: A locker can be used to lock each run of a job to a single instance of gocron.
  • Implementations: go-co-op lockers
Events

Job events can trigger actions.

Options

Many job and scheduler options are available.

  • Job options: Job options can be set when creating a job using NewJob.
  • Global job options: Global job options can be set when creating a scheduler using NewScheduler and the WithGlobalJobOptions option.
  • Scheduler options: Scheduler options can be set when creating a scheduler using NewScheduler.
Logging

Logs can be enabled.

  • Logger: The Logger interface can be implemented with your desired logging library. The provided NewLogger uses the standard library's log package.
Testing

The gocron library is set up to enable testing.

Supporters

We appreciate the support for free and open source software!

This project is supported by:

Star History

Star History Chart

Documentation

Index

Examples

Constants

View Source
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

View Source
var (
	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")
	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")
	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")
	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")
	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")
	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")
	ErrWithNameEmpty                 = fmt.Errorf("gocron: WithName: name must not be empty")
	ErrWithStartDateTimePast         = fmt.Errorf("gocron: WithStartDateTime: start must not be in the past")
	ErrWithStopTimeoutZeroOrNegative = fmt.Errorf("gocron: WithStopTimeout: timeout must be greater than 0")
)

Public error definitions

Functions

This section is empty.

Types

type AtTime

type AtTime func() atTime

AtTime defines a function that returns the internal atTime

func NewAtTime

func NewAtTime(hours, minutes, seconds uint) AtTime

NewAtTime provide the hours, minutes and seconds at which the job should be run

type AtTimes

type AtTimes func() []AtTime

AtTimes define a list of AtTime

func NewAtTimes

func NewAtTimes(atTime AtTime, atTimes ...AtTime) AtTimes

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 regardless of any returned error value, and 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 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() uuid.UUID
	LastRun() (time.Time, error)
	Name() string
	NextRun() (time.Time, error)
	Tags() []string
}

Job provides the available methods on the job available to the caller.

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 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

type JobOption func(*internalJob) error

JobOption defines the constructor for job options.

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 WithLimitedRuns

func WithLimitedRuns(limit uint) JobOption

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)
fmt.Printf("no jobs in scheduler: %v\n", s.Jobs())
_ = s.StopJobs()
Output:

one, 2
no jobs in scheduler: []

func WithName

func WithName(name string) JobOption

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

func WithSingletonMode(mode LimitMode) JobOption

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()
time.Sleep(20 * time.Millisecond)

next, _ := j.NextRun()
fmt.Println(next)

_ = s.StopJobs()
Output:

9999-09-09 09:09:09.000000009 +0000 UTC

func WithTags

func WithTags(tags ...string) JobOption

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 LimitMode

type LimitMode int

LimitMode defines the modes used for handling jobs that reach the limit provided in WithLimitConcurrentJobs

type Lock

type Lock interface {
	Unlock(ctx context.Context) error
}

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.

const (
	LogLevelError LogLevel = iota
	LogLevelWarn
	LogLevelInfo
	LogLevelDebug
)

The different log levels that can be used.

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.

func NewLogger

func NewLogger(level LogLevel) Logger

NewLogger returns a new Logger that logs at the given level.

type Scheduler

type Scheduler interface {
	Jobs() []Job
	NewJob(JobDefinition, Task, ...JobOption) (Job, error)
	RemoveByTags(...string)
	RemoveJob(uuid.UUID) error
	Start()
	StopJobs() error
	Shutdown() error
	Update(uuid.UUID, JobDefinition, Task, ...JobOption) (Job, error)
}

Scheduler defines the interface for the Scheduler.

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 _ Elector = (*myElector)(nil)
//
//type myElector struct{}
//
//func (m myElector) IsLeader(_ context.Context) error {
//	return nil
//}
//
//elector := myElector{}
//
//_, _ = NewScheduler(
//	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 _ 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{}
//
//_, _ = NewScheduler(
//	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.

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 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

type StartAtOption func(*internalJob) error

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 Task

type Task func() task

Task defines a function that returns the task function and parameters.

func NewTask

func NewTask(function any, parameters ...any) Task

NewTask provides the job's task function and parameters.

type Weekdays

type Weekdays func() []time.Weekday

Weekdays defines a function that returns a list of week days.

func NewWeekdays

func NewWeekdays(weekday time.Weekday, weekdays ...time.Weekday) Weekdays

NewWeekdays provide the days of the week the job should run.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL