2023-11-14 16:26:44 +00:00
|
|
|
# gocron: A Golang Job Scheduling Package
|
2023-11-08 17:11:42 +00:00
|
|
|
|
|
|
|
|
[](https://github.com/go-co-op/gocron/actions)
|
|
|
|
|
 [](https://pkg.go.dev/github.com/go-co-op/gocron/v2)
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
[<img src="https://img.shields.io/badge/gophers-gocron-brightgreen?logo=slack">](https://gophers.slack.com/archives/CQ7T0T1FW)
|
|
|
|
|
|
|
|
|
|
## Quick Start
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
go get github.com/go-co-op/gocron/v2
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```golang
|
|
|
|
|
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
|
2023-12-28 20:23:53 +00:00
|
|
|
},
|
2023-11-08 17:11:42 +00:00
|
|
|
"hello",
|
|
|
|
|
1,
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
// handle error
|
|
|
|
|
}
|
|
|
|
|
// each job has a unique id
|
|
|
|
|
fmt.Println(j.ID())
|
|
|
|
|
|
|
|
|
|
// start the scheduler
|
|
|
|
|
s.Start()
|
|
|
|
|
|
2024-01-17 17:50:33 +00:00
|
|
|
// block until you are ready to shut down
|
|
|
|
|
select {
|
|
|
|
|
case <-time.After(time.Minute):
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-08 17:11:42 +00:00
|
|
|
// when you're done, shut it down
|
|
|
|
|
err = s.Shutdown()
|
|
|
|
|
if err != nil {
|
|
|
|
|
// handle error
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2024-03-12 13:37:11 +00:00
|
|
|
## Examples
|
|
|
|
|
|
|
|
|
|
- [Go doc examples](https://pkg.go.dev/github.com/go-co-op/gocron/v2#pkg-examples)
|
|
|
|
|
- [Examples directory](examples)
|
|
|
|
|
|
2023-12-11 16:39:59 +00:00
|
|
|
## 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)
|
|
|
|
|
|
|
|
|
|
|
2023-11-08 17:11:42 +00:00
|
|
|
## Features
|
|
|
|
|
|
2023-12-13 16:48:53 +00:00
|
|
|
### Job types
|
|
|
|
|
Jobs can be run at various intervals.
|
|
|
|
|
- [**Duration**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#DurationJob):
|
|
|
|
|
Jobs can be run at a fixed `time.Duration`.
|
|
|
|
|
- [**Random duration**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#DurationRandomJob):
|
|
|
|
|
Jobs can be run at a random `time.Duration` between a min and max.
|
|
|
|
|
- [**Cron**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#CronJob):
|
|
|
|
|
Jobs can be run using a crontab.
|
|
|
|
|
- [**Daily**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#DailyJob):
|
|
|
|
|
Jobs can be run every x days at specific times.
|
|
|
|
|
- [**Weekly**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WeeklyJob):
|
|
|
|
|
Jobs can be run every x weeks on specific days of the week and at specific times.
|
|
|
|
|
- [**Monthly**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#MonthlyJob):
|
|
|
|
|
Jobs can be run every x months on specific days of the month and at specific times.
|
2023-12-19 03:13:37 +00:00
|
|
|
- [**One time**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#OneTimeJob):
|
2024-06-23 18:14:35 +00:00
|
|
|
Jobs can be run at specific time(s) (either once or many times).
|
2023-12-13 16:48:53 +00:00
|
|
|
|
|
|
|
|
### Concurrency Limits
|
|
|
|
|
Jobs can be limited individually or across the entire scheduler.
|
|
|
|
|
- [**Per job limiting with singleton mode**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithSingletonMode):
|
|
|
|
|
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**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithLimitConcurrentJobs):
|
|
|
|
|
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**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithDistributedElector):
|
|
|
|
|
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.
|
2024-01-17 21:39:11 +00:00
|
|
|
- Implementations: [go-co-op electors](https://github.com/go-co-op?q=-elector&type=all&language=&sort=)
|
|
|
|
|
(don't see what you need? request on slack to get a repo created to contribute it!)
|
2023-12-13 16:48:53 +00:00
|
|
|
- [**Locker**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithDistributedLocker):
|
|
|
|
|
A locker can be used to lock each run of a job to a single instance of gocron.
|
2024-04-22 18:52:27 +00:00
|
|
|
Locker can be at job or scheduler, if it is defined both at job and scheduler then locker of job will take precedence.
|
2025-05-16 19:15:33 +00:00
|
|
|
- See Notes in the doc for [Locker](https://pkg.go.dev/github.com/go-co-op/gocron/v2#Locker) for
|
|
|
|
|
details and limitations of the locker design.
|
2024-01-17 21:39:11 +00:00
|
|
|
- Implementations: [go-co-op lockers](https://github.com/go-co-op?q=-lock&type=all&language=&sort=)
|
|
|
|
|
(don't see what you need? request on slack to get a repo created to contribute it!)
|
2023-12-13 16:48:53 +00:00
|
|
|
|
|
|
|
|
### Events
|
|
|
|
|
Job events can trigger actions.
|
|
|
|
|
- [**Listeners**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithEventListeners):
|
|
|
|
|
Can be added to a job, with [event listeners](https://pkg.go.dev/github.com/go-co-op/gocron/v2#EventListener),
|
|
|
|
|
or all jobs across the
|
|
|
|
|
[scheduler](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithGlobalJobOptions)
|
|
|
|
|
to listen for job events and trigger actions.
|
|
|
|
|
|
|
|
|
|
### Options
|
|
|
|
|
Many job and scheduler options are available.
|
|
|
|
|
- [**Job options**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#JobOption):
|
|
|
|
|
Job options can be set when creating a job using `NewJob`.
|
|
|
|
|
- [**Global job options**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithGlobalJobOptions):
|
|
|
|
|
Global job options can be set when creating a scheduler using `NewScheduler`
|
|
|
|
|
and the `WithGlobalJobOptions` option.
|
|
|
|
|
- [**Scheduler options**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#SchedulerOption):
|
|
|
|
|
Scheduler options can be set when creating a scheduler using `NewScheduler`.
|
|
|
|
|
|
|
|
|
|
### Logging
|
|
|
|
|
Logs can be enabled.
|
|
|
|
|
- [Logger](https://pkg.go.dev/github.com/go-co-op/gocron/v2#Logger):
|
|
|
|
|
The Logger interface can be implemented with your desired logging library.
|
|
|
|
|
The provided NewLogger uses the standard library's log package.
|
|
|
|
|
|
2024-01-17 21:39:11 +00:00
|
|
|
### Metrics
|
|
|
|
|
Metrics may be collected from the execution of each job.
|
|
|
|
|
- [**Monitor**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#Monitor):
|
2024-12-12 04:23:57 +00:00
|
|
|
- [**MonitorStatus**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#MonitorStatus) (includes status and error (if any) of the Job)
|
2024-01-17 21:39:11 +00:00
|
|
|
A monitor can be used to collect metrics for each job from a scheduler.
|
|
|
|
|
- Implementations: [go-co-op monitors](https://github.com/go-co-op?q=-monitor&type=all&language=&sort=)
|
|
|
|
|
(don't see what you need? request on slack to get a repo created to contribute it!)
|
|
|
|
|
|
2023-12-13 16:48:53 +00:00
|
|
|
### Testing
|
|
|
|
|
The gocron library is set up to enable testing.
|
|
|
|
|
- Mocks are provided in [the mock package](mocks) using [gomock](https://github.com/uber-go/mock).
|
|
|
|
|
- Time can be mocked by passing in a [FakeClock](https://pkg.go.dev/github.com/jonboulle/clockwork#FakeClock)
|
|
|
|
|
to [WithClock](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithClock) -
|
|
|
|
|
see the [example on WithClock](https://pkg.go.dev/github.com/go-co-op/gocron/v2#example-WithClock).
|
2023-11-08 17:11:42 +00:00
|
|
|
|
|
|
|
|
## Supporters
|
|
|
|
|
|
2023-12-11 16:39:59 +00:00
|
|
|
We appreciate the support for free and open source software!
|
|
|
|
|
|
2023-12-12 20:46:14 +00:00
|
|
|
This project is supported by:
|
|
|
|
|
|
2025-04-03 17:27:12 +00:00
|
|
|
[JetBrains](https://www.jetbrains.com/?from=gocron)
|
2024-12-06 20:06:44 +00:00
|
|
|
|
2025-04-03 17:27:12 +00:00
|
|
|
<a href="https://www.jetbrains.com/?from=gocron">
|
|
|
|
|
<picture>
|
|
|
|
|
<source media="(prefers-color-scheme: dark)" srcset="assets/jetbrains-mono-white.png" />
|
|
|
|
|
<source media="(prefers-color-scheme: light)" srcset="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.png" />
|
|
|
|
|
<img alt="JetBrains logo" src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.png" />
|
|
|
|
|
</picture>
|
|
|
|
|
</a>
|
2024-12-06 20:06:44 +00:00
|
|
|
|
|
|
|
|
[Sentry](https://sentry.io/welcome/)
|
2023-11-08 17:11:42 +00:00
|
|
|
|
2025-04-03 17:27:12 +00:00
|
|
|
<a href="https://sentry.io/?utm_source=github&utm_medium=logo">
|
|
|
|
|
<picture>
|
|
|
|
|
<source media="(prefers-color-scheme: dark)" srcset="assets/sentry-wordmark-light-280x84.png" />
|
|
|
|
|
<source media="(prefers-color-scheme: light)" srcset="https://sentry-brand.storage.googleapis.com/sentry-wordmark-dark-280x84.png" />
|
|
|
|
|
<img alt="Sentry logo" src="https://sentry-brand.storage.googleapis.com/sentry-wordmark-dark-280x84.png" />
|
|
|
|
|
</picture>
|
|
|
|
|
</a>
|
2025-01-31 16:25:26 +00:00
|
|
|
|
2023-11-08 17:11:42 +00:00
|
|
|
## Star History
|
|
|
|
|
|
2025-04-03 17:27:12 +00:00
|
|
|
<a href="https://www.star-history.com/#go-co-op/gocron&Date">
|
|
|
|
|
<picture>
|
|
|
|
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=go-co-op/gocron&type=Date&theme=dark" />
|
|
|
|
|
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=go-co-op/gocron&type=Date" />
|
|
|
|
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=go-co-op/gocron&type=Date" />
|
|
|
|
|
</picture>
|
|
|
|
|
</a>
|