Update docs, tests, and release prep (#629)

This commit is contained in:
John Roesler 2023-12-11 10:39:59 -06:00 committed by GitHub
parent 5814fbcb6f
commit aa4400d224
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 230 additions and 199 deletions

View File

@ -8,15 +8,6 @@ gocron is a job scheduling package which lets you run Go functions at pre-determ
If you want to chat, you can find us on Slack at 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) [<img src="https://img.shields.io/badge/gophers-gocron-brightgreen?logo=slack">](https://gophers.slack.com/archives/CQ7T0T1FW)
## Concepts
- **Job**: The encapsulates a "task", which is made up of a go func and any function parameters, and then
provides the scheduler with the time the job should be scheduled to run.
- **Executor**: The executor, calls the "task" function and manages the complexities of different job
execution timing (e.g. singletons that shouldn't overrun each other, limiting the max number of jobs running)
- **Scheduler**: The scheduler keeps track of all the jobs and sends each job to the executor when
it is ready to be run.
## Quick Start ## Quick Start
``` ```
@ -70,6 +61,16 @@ func main() {
} }
``` ```
## 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 ## Features
- **Job types**: Jobs can be run at various intervals. - **Job types**: Jobs can be run at various intervals.
@ -85,7 +86,7 @@ func main() {
Jobs can be run every x weeks on specific days of the week and at specific times. 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): - [**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. Jobs can be run every x months on specific days of the month and at specific times.
- **Limited Concurrency**: Jobs can be limited individually or across the entire scheduler. - **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): - [**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) Jobs can be limited to a single concurrent execution that either reschedules (skips overlapping executions)
or queues (waits for the previous execution to finish). or queues (waits for the previous execution to finish).
@ -93,6 +94,7 @@ func main() {
Jobs can be limited to a certain number of concurrent executions across the entire scheduler 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 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). 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. - **Distributed instances of gocron**: Multiple instances of gocron can be run.
- [**Elector**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithDistributedElector): - [**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 An elector can be used to elect a single instance of gocron to run as the primary with the
@ -103,31 +105,33 @@ func main() {
- Implementations: [go-co-op lockers](https://github.com/go-co-op?q=-lock&type=all&language=&sort=) - Implementations: [go-co-op lockers](https://github.com/go-co-op?q=-lock&type=all&language=&sort=)
- **Events**: Job events can trigger actions. - **Events**: Job events can trigger actions.
- [**Listeners**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithEventListeners): - [**Listeners**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithEventListeners):
[Event listeners](https://pkg.go.dev/github.com/go-co-op/gocron/v2#EventListener) Can be added to a job, with [event listeners](https://pkg.go.dev/github.com/go-co-op/gocron/v2#EventListener),
can be added to a job or all jobs in the or all jobs across the
[scheduler](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithGlobalJobOptions) [scheduler](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithGlobalJobOptions)
to listen for job events and trigger actions. to listen for job events and trigger actions.
- **Options**: Many job and scheduler options are available - **Options**: Many job and scheduler options are available.
- [**Job options**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#JobOption): - [**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`. 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**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithGlobalJobOptions):
Global job options can be set when creating a scheduler using `NewScheduler`. 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**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#SchedulerOption):
Scheduler options can be set when creating a scheduler using `NewScheduler`. Scheduler options can be set when creating a scheduler using `NewScheduler`.
- **Logging**: Logs can be enabled. - **Logging**: Logs can be enabled.
- [Logger](https://pkg.go.dev/github.com/go-co-op/gocron/v2#Logger): - [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 Logger interface can be implemented with your desired logging library.
The provided NewLogger uses the standard library's log package. The provided NewLogger uses the standard library's log package.
- **Mocking**: The gocron library is set up to enable testing. - **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). - 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) - 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) - to [WithClock](https://pkg.go.dev/github.com/go-co-op/gocron/v2#WithClock) -
see the example on WithClock in the go-docs. see the [example on WithClock](https://pkg.go.dev/github.com/go-co-op/gocron/v2#example-WithClock).
## Supporters ## Supporters
[Jetbrains](https://www.jetbrains.com/?from=gocron) supports this project with Intellij licenses. We appreciate the support for free and open source software!
We appreciate their support for free and open source software!
- [Jetbrains](https://www.jetbrains.com/?from=gocron) supports this project with Intellij licenses.
## Star History ## Star History

View File

@ -1,4 +1,4 @@
//go:generate mockgen -source=distributed.go -destination=mocks/distributed.go -package=gocronmocks //go:generate mockgen -destination=mocks/distributed.go -package=gocronmocks . Elector,Locker,Lock
package gocron package gocron
import ( import (

View File

@ -231,6 +231,13 @@ func (e *executor) limitModeRunner(name string, in chan uuid.UUID, wg *waitGroup
return return
case e.jobIDsOut <- j.id: case e.jobIDsOut <- j.id:
} }
// remove the limiter block to allow another job to be scheduled
if limitMode == LimitModeReschedule {
select {
case <-rescheduleLimiter:
default:
}
}
continue continue
} }
e.limitMode.singletonJobs[id] = struct{}{} e.limitMode.singletonJobs[id] = struct{}{}

5
go.mod
View File

@ -8,14 +8,13 @@ require (
github.com/robfig/cron/v3 v3.0.1 github.com/robfig/cron/v3 v3.0.1
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
go.uber.org/goleak v1.3.0 go.uber.org/goleak v1.3.0
golang.org/x/exp v0.0.0-20231006140011-7918f672742d golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb
) )
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

12
go.sum
View File

@ -5,12 +5,12 @@ github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
@ -19,10 +19,10 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

2
job.go
View File

@ -1,4 +1,4 @@
//go:generate mockgen -source=job.go -destination=mocks/job.go -package=gocronmocks //go:generate mockgen -destination=mocks/job.go -package=gocronmocks . Job
package gocron package gocron
import ( import (

View File

@ -313,10 +313,9 @@ func TestJob_LastRun(t *testing.T) {
testTime := time.Date(2000, 1, 1, 0, 0, 0, 0, time.Local) testTime := time.Date(2000, 1, 1, 0, 0, 0, 0, time.Local)
fakeClock := clockwork.NewFakeClockAt(testTime) fakeClock := clockwork.NewFakeClockAt(testTime)
s, err := newTestScheduler( s := newTestScheduler(t,
WithClock(fakeClock), WithClock(fakeClock),
) )
require.NoError(t, err)
j, err := s.NewJob( j, err := s.NewJob(
DurationJob( DurationJob(

View File

@ -1,4 +1,4 @@
//go:generate mockgen -source=logger.go -destination=mocks/logger.go -package=gocronmocks //go:generate mockgen -destination=mocks/logger.go -package=gocronmocks . Logger
package gocron package gocron
import ( import (

View File

@ -1,9 +1,9 @@
// Code generated by MockGen. DO NOT EDIT. // Code generated by MockGen. DO NOT EDIT.
// Source: distributed.go // Source: github.com/go-co-op/gocron/v2 (interfaces: Elector,Locker,Lock)
// //
// Generated by this command: // Generated by this command:
// //
// mockgen -source=distributed.go -destination=mocks/distributed.go -package=gocronmocks // mockgen -destination=mocks/distributed.go -package=gocronmocks . Elector,Locker,Lock
// //
// Package gocronmocks is a generated GoMock package. // Package gocronmocks is a generated GoMock package.
package gocronmocks package gocronmocks
@ -12,6 +12,7 @@ import (
context "context" context "context"
reflect "reflect" reflect "reflect"
gocron "github.com/go-co-op/gocron/v2"
gomock "go.uber.org/mock/gomock" gomock "go.uber.org/mock/gomock"
) )
@ -51,3 +52,78 @@ func (mr *MockElectorMockRecorder) IsLeader(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsLeader", reflect.TypeOf((*MockElector)(nil).IsLeader), arg0) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsLeader", reflect.TypeOf((*MockElector)(nil).IsLeader), arg0)
} }
// MockLocker is a mock of Locker interface.
type MockLocker struct {
ctrl *gomock.Controller
recorder *MockLockerMockRecorder
}
// MockLockerMockRecorder is the mock recorder for MockLocker.
type MockLockerMockRecorder struct {
mock *MockLocker
}
// NewMockLocker creates a new mock instance.
func NewMockLocker(ctrl *gomock.Controller) *MockLocker {
mock := &MockLocker{ctrl: ctrl}
mock.recorder = &MockLockerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockLocker) EXPECT() *MockLockerMockRecorder {
return m.recorder
}
// Lock mocks base method.
func (m *MockLocker) Lock(arg0 context.Context, arg1 string) (gocron.Lock, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Lock", arg0, arg1)
ret0, _ := ret[0].(gocron.Lock)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Lock indicates an expected call of Lock.
func (mr *MockLockerMockRecorder) Lock(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lock", reflect.TypeOf((*MockLocker)(nil).Lock), arg0, arg1)
}
// MockLock is a mock of Lock interface.
type MockLock struct {
ctrl *gomock.Controller
recorder *MockLockMockRecorder
}
// MockLockMockRecorder is the mock recorder for MockLock.
type MockLockMockRecorder struct {
mock *MockLock
}
// NewMockLock creates a new mock instance.
func NewMockLock(ctrl *gomock.Controller) *MockLock {
mock := &MockLock{ctrl: ctrl}
mock.recorder = &MockLockMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockLock) EXPECT() *MockLockMockRecorder {
return m.recorder
}
// Unlock mocks base method.
func (m *MockLock) Unlock(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Unlock", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Unlock indicates an expected call of Unlock.
func (mr *MockLockMockRecorder) Unlock(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockLock)(nil).Unlock), arg0)
}

View File

@ -3,7 +3,7 @@ module github.com/go-co-op/gocronmocks/v2
go 1.20 go 1.20
require ( require (
github.com/go-co-op/gocron/v2 v2.0.0-rc1 github.com/go-co-op/gocron/v2 v2.0.0-rc4
github.com/google/uuid v1.4.0 github.com/google/uuid v1.4.0
go.uber.org/mock v0.3.0 go.uber.org/mock v0.3.0
) )
@ -11,5 +11,5 @@ require (
require ( require (
github.com/jonboulle/clockwork v0.4.0 // indirect github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb // indirect
) )

View File

@ -1,6 +1,6 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/go-co-op/gocron/v2 v2.0.0-rc1 h1:qkj0WVO6uh6ibZa2CQ0Ifxk3A+c6rawZnIby94/5sAM= github.com/go-co-op/gocron/v2 v2.0.0-rc4 h1:KFYg2CzyHZwPZL/uNnQKEyeL9oKEUQbiLThArcZaVmw=
github.com/go-co-op/gocron/v2 v2.0.0-rc1/go.mod h1:3SLoqKnyORFVN0VvFFb1383hM4WD9XHBPn9aUUp7sQs= github.com/go-co-op/gocron/v2 v2.0.0-rc4/go.mod h1:3SLoqKnyORFVN0VvFFb1383hM4WD9XHBPn9aUUp7sQs=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
@ -12,6 +12,6 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -1,9 +1,9 @@
// Code generated by MockGen. DO NOT EDIT. // Code generated by MockGen. DO NOT EDIT.
// Source: job.go // Source: github.com/go-co-op/gocron/v2 (interfaces: Job)
// //
// Generated by this command: // Generated by this command:
// //
// mockgen -source=job.go -destination=mocks/job.go -package=gocronmocks // mockgen -destination=mocks/job.go -package=gocronmocks . Job
// //
// Package gocronmocks is a generated GoMock package. // Package gocronmocks is a generated GoMock package.
package gocronmocks package gocronmocks
@ -16,80 +16,6 @@ import (
gomock "go.uber.org/mock/gomock" gomock "go.uber.org/mock/gomock"
) )
// MockJobDefinition is a mock of JobDefinition interface.
type MockJobDefinition struct {
ctrl *gomock.Controller
recorder *MockJobDefinitionMockRecorder
}
// MockJobDefinitionMockRecorder is the mock recorder for MockJobDefinition.
type MockJobDefinitionMockRecorder struct {
mock *MockJobDefinition
}
// NewMockJobDefinition creates a new mock instance.
func NewMockJobDefinition(ctrl *gomock.Controller) *MockJobDefinition {
mock := &MockJobDefinition{ctrl: ctrl}
mock.recorder = &MockJobDefinitionMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockJobDefinition) EXPECT() *MockJobDefinitionMockRecorder {
return m.recorder
}
// setup mocks base method.
func (m *MockJobDefinition) setup(arg0 *internalJob, arg1 *time.Location) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "setup", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// setup indicates an expected call of setup.
func (mr *MockJobDefinitionMockRecorder) setup(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "setup", reflect.TypeOf((*MockJobDefinition)(nil).setup), arg0, arg1)
}
// MockjobSchedule is a mock of jobSchedule interface.
type MockjobSchedule struct {
ctrl *gomock.Controller
recorder *MockjobScheduleMockRecorder
}
// MockjobScheduleMockRecorder is the mock recorder for MockjobSchedule.
type MockjobScheduleMockRecorder struct {
mock *MockjobSchedule
}
// NewMockjobSchedule creates a new mock instance.
func NewMockjobSchedule(ctrl *gomock.Controller) *MockjobSchedule {
mock := &MockjobSchedule{ctrl: ctrl}
mock.recorder = &MockjobScheduleMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockjobSchedule) EXPECT() *MockjobScheduleMockRecorder {
return m.recorder
}
// next mocks base method.
func (m *MockjobSchedule) next(lastRun time.Time) time.Time {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "next", lastRun)
ret0, _ := ret[0].(time.Time)
return ret0
}
// next indicates an expected call of next.
func (mr *MockjobScheduleMockRecorder) next(lastRun any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "next", reflect.TypeOf((*MockjobSchedule)(nil).next), lastRun)
}
// MockJob is a mock of Job interface. // MockJob is a mock of Job interface.
type MockJob struct { type MockJob struct {
ctrl *gomock.Controller ctrl *gomock.Controller

View File

@ -1,9 +1,9 @@
// Code generated by MockGen. DO NOT EDIT. // Code generated by MockGen. DO NOT EDIT.
// Source: logger.go // Source: github.com/go-co-op/gocron/v2 (interfaces: Logger)
// //
// Generated by this command: // Generated by this command:
// //
// mockgen -source=logger.go -destination=mocks/logger.go -package=gocronmocks // mockgen -destination=mocks/logger.go -package=gocronmocks . Logger
// //
// Package gocronmocks is a generated GoMock package. // Package gocronmocks is a generated GoMock package.
package gocronmocks package gocronmocks
@ -38,69 +38,69 @@ func (m *MockLogger) EXPECT() *MockLoggerMockRecorder {
} }
// Debug mocks base method. // Debug mocks base method.
func (m *MockLogger) Debug(msg string, args ...any) { func (m *MockLogger) Debug(arg0 string, arg1 ...any) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
varargs := []any{msg} varargs := []any{arg0}
for _, a := range args { for _, a := range arg1 {
varargs = append(varargs, a) varargs = append(varargs, a)
} }
m.ctrl.Call(m, "Debug", varargs...) m.ctrl.Call(m, "Debug", varargs...)
} }
// Debug indicates an expected call of Debug. // Debug indicates an expected call of Debug.
func (mr *MockLoggerMockRecorder) Debug(msg any, args ...any) *gomock.Call { func (mr *MockLoggerMockRecorder) Debug(arg0 any, arg1 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
varargs := append([]any{msg}, args...) varargs := append([]any{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockLogger)(nil).Debug), varargs...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockLogger)(nil).Debug), varargs...)
} }
// Error mocks base method. // Error mocks base method.
func (m *MockLogger) Error(msg string, args ...any) { func (m *MockLogger) Error(arg0 string, arg1 ...any) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
varargs := []any{msg} varargs := []any{arg0}
for _, a := range args { for _, a := range arg1 {
varargs = append(varargs, a) varargs = append(varargs, a)
} }
m.ctrl.Call(m, "Error", varargs...) m.ctrl.Call(m, "Error", varargs...)
} }
// Error indicates an expected call of Error. // Error indicates an expected call of Error.
func (mr *MockLoggerMockRecorder) Error(msg any, args ...any) *gomock.Call { func (mr *MockLoggerMockRecorder) Error(arg0 any, arg1 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
varargs := append([]any{msg}, args...) varargs := append([]any{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockLogger)(nil).Error), varargs...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockLogger)(nil).Error), varargs...)
} }
// Info mocks base method. // Info mocks base method.
func (m *MockLogger) Info(msg string, args ...any) { func (m *MockLogger) Info(arg0 string, arg1 ...any) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
varargs := []any{msg} varargs := []any{arg0}
for _, a := range args { for _, a := range arg1 {
varargs = append(varargs, a) varargs = append(varargs, a)
} }
m.ctrl.Call(m, "Info", varargs...) m.ctrl.Call(m, "Info", varargs...)
} }
// Info indicates an expected call of Info. // Info indicates an expected call of Info.
func (mr *MockLoggerMockRecorder) Info(msg any, args ...any) *gomock.Call { func (mr *MockLoggerMockRecorder) Info(arg0 any, arg1 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
varargs := append([]any{msg}, args...) varargs := append([]any{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockLogger)(nil).Info), varargs...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockLogger)(nil).Info), varargs...)
} }
// Warn mocks base method. // Warn mocks base method.
func (m *MockLogger) Warn(msg string, args ...any) { func (m *MockLogger) Warn(arg0 string, arg1 ...any) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
varargs := []any{msg} varargs := []any{arg0}
for _, a := range args { for _, a := range arg1 {
varargs = append(varargs, a) varargs = append(varargs, a)
} }
m.ctrl.Call(m, "Warn", varargs...) m.ctrl.Call(m, "Warn", varargs...)
} }
// Warn indicates an expected call of Warn. // Warn indicates an expected call of Warn.
func (mr *MockLoggerMockRecorder) Warn(msg any, args ...any) *gomock.Call { func (mr *MockLoggerMockRecorder) Warn(arg0 any, arg1 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
varargs := append([]any{msg}, args...) varargs := append([]any{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Warn", reflect.TypeOf((*MockLogger)(nil).Warn), varargs...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Warn", reflect.TypeOf((*MockLogger)(nil).Warn), varargs...)
} }

View File

@ -1,9 +1,9 @@
// Code generated by MockGen. DO NOT EDIT. // Code generated by MockGen. DO NOT EDIT.
// Source: scheduler.go // Source: github.com/go-co-op/gocron/v2 (interfaces: Scheduler)
// //
// Generated by this command: // Generated by this command:
// //
// mockgen -source=scheduler.go -destination=mocks/scheduler.go -package=gocronmocks // mockgen -destination=mocks/scheduler.go -package=gocronmocks . Scheduler
// //
// Package gocronmocks is a generated GoMock package. // Package gocronmocks is a generated GoMock package.
package gocronmocks package gocronmocks
@ -11,7 +11,7 @@ package gocronmocks
import ( import (
reflect "reflect" reflect "reflect"
v2 "github.com/go-co-op/gocron/v2" gocron "github.com/go-co-op/gocron/v2"
uuid "github.com/google/uuid" uuid "github.com/google/uuid"
gomock "go.uber.org/mock/gomock" gomock "go.uber.org/mock/gomock"
) )
@ -40,10 +40,10 @@ func (m *MockScheduler) EXPECT() *MockSchedulerMockRecorder {
} }
// Jobs mocks base method. // Jobs mocks base method.
func (m *MockScheduler) Jobs() []v2.Job { func (m *MockScheduler) Jobs() []gocron.Job {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Jobs") ret := m.ctrl.Call(m, "Jobs")
ret0, _ := ret[0].([]v2.Job) ret0, _ := ret[0].([]gocron.Job)
return ret0 return ret0
} }
@ -54,14 +54,14 @@ func (mr *MockSchedulerMockRecorder) Jobs() *gomock.Call {
} }
// NewJob mocks base method. // NewJob mocks base method.
func (m *MockScheduler) NewJob(arg0 v2.JobDefinition, arg1 v2.Task, arg2 ...v2.JobOption) (v2.Job, error) { func (m *MockScheduler) NewJob(arg0 gocron.JobDefinition, arg1 gocron.Task, arg2 ...gocron.JobOption) (gocron.Job, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
varargs := []any{arg0, arg1} varargs := []any{arg0, arg1}
for _, a := range arg2 { for _, a := range arg2 {
varargs = append(varargs, a) varargs = append(varargs, a)
} }
ret := m.ctrl.Call(m, "NewJob", varargs...) ret := m.ctrl.Call(m, "NewJob", varargs...)
ret0, _ := ret[0].(v2.Job) ret0, _ := ret[0].(gocron.Job)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }
@ -144,14 +144,14 @@ func (mr *MockSchedulerMockRecorder) StopJobs() *gomock.Call {
} }
// Update mocks base method. // Update mocks base method.
func (m *MockScheduler) Update(arg0 uuid.UUID, arg1 v2.JobDefinition, arg2 v2.Task, arg3 ...v2.JobOption) (v2.Job, error) { func (m *MockScheduler) Update(arg0 uuid.UUID, arg1 gocron.JobDefinition, arg2 gocron.Task, arg3 ...gocron.JobOption) (gocron.Job, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2} varargs := []any{arg0, arg1, arg2}
for _, a := range arg3 { for _, a := range arg3 {
varargs = append(varargs, a) varargs = append(varargs, a)
} }
ret := m.ctrl.Call(m, "Update", varargs...) ret := m.ctrl.Call(m, "Update", varargs...)
ret0, _ := ret[0].(v2.Job) ret0, _ := ret[0].(gocron.Job)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }

View File

@ -1,4 +1,4 @@
//go:generate mockgen -source=scheduler.go -destination=mocks/scheduler.go -package=gocronmocks //go:generate mockgen -destination=mocks/scheduler.go -package=gocronmocks . Scheduler
package gocron package gocron
import ( import (

View File

@ -14,7 +14,7 @@ import (
"go.uber.org/goleak" "go.uber.org/goleak"
) )
func newTestScheduler(options ...SchedulerOption) (Scheduler, error) { func newTestScheduler(t *testing.T, options ...SchedulerOption) Scheduler {
// default test options // default test options
out := []SchedulerOption{ out := []SchedulerOption{
WithLogger(NewLogger(LogLevelDebug)), WithLogger(NewLogger(LogLevelDebug)),
@ -23,7 +23,9 @@ func newTestScheduler(options ...SchedulerOption) (Scheduler, error) {
// append any additional options 2nd to override defaults if needed // append any additional options 2nd to override defaults if needed
out = append(out, options...) out = append(out, options...)
return NewScheduler(out...) s, err := NewScheduler(out...)
require.NoError(t, err)
return s
} }
func TestScheduler_OneSecond_NoOptions(t *testing.T) { func TestScheduler_OneSecond_NoOptions(t *testing.T) {
@ -66,10 +68,9 @@ func TestScheduler_OneSecond_NoOptions(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler() s := newTestScheduler(t)
require.NoError(t, err)
_, err = s.NewJob(tt.jd, tt.tsk) _, err := s.NewJob(tt.jd, tt.tsk)
require.NoError(t, err) require.NoError(t, err)
s.Start() s.Start()
@ -147,10 +148,9 @@ func TestScheduler_LongRunningJobs(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler(tt.options...) s := newTestScheduler(t, tt.options...)
require.NoError(t, err)
_, err = s.NewJob(tt.jd, tt.tsk, tt.opts...) _, err := s.NewJob(tt.jd, tt.tsk, tt.opts...)
require.NoError(t, err) require.NoError(t, err)
s.Start() s.Start()
@ -217,8 +217,7 @@ func TestScheduler_Update(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler() s := newTestScheduler(t)
require.NoError(t, err)
j, err := s.NewJob(tt.initialJob, tt.tsk) j, err := s.NewJob(tt.initialJob, tt.tsk)
require.NoError(t, err) require.NoError(t, err)
@ -294,12 +293,11 @@ func TestScheduler_StopTimeout(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
testDoneCtx, cancel := context.WithCancel(context.Background()) testDoneCtx, cancel := context.WithCancel(context.Background())
s, err := newTestScheduler( s := newTestScheduler(t,
WithStopTimeout(time.Millisecond*100), WithStopTimeout(time.Millisecond*100),
) )
require.NoError(t, err)
_, err = s.NewJob(tt.jd, NewTask(tt.f, testDoneCtx), tt.opts...) _, err := s.NewJob(tt.jd, NewTask(tt.f, testDoneCtx), tt.opts...)
require.NoError(t, err) require.NoError(t, err)
s.Start() s.Start()
@ -316,11 +314,11 @@ func TestScheduler_Shutdown(t *testing.T) {
goleak.VerifyNone(t) goleak.VerifyNone(t)
t.Run("start, stop, start, shutdown", func(t *testing.T) { t.Run("start, stop, start, shutdown", func(t *testing.T) {
s, err := newTestScheduler( s := newTestScheduler(t,
WithStopTimeout(time.Second), WithStopTimeout(time.Second),
) )
require.NoError(t, err)
_, err = s.NewJob( _, err := s.NewJob(
DurationJob( DurationJob(
50*time.Millisecond, 50*time.Millisecond,
), ),
@ -346,10 +344,9 @@ func TestScheduler_Shutdown(t *testing.T) {
}) })
t.Run("calling Job methods after shutdown errors", func(t *testing.T) { t.Run("calling Job methods after shutdown errors", func(t *testing.T) {
s, err := newTestScheduler( s := newTestScheduler(t,
WithStopTimeout(time.Second), WithStopTimeout(time.Second),
) )
require.NoError(t, err)
j, err := s.NewJob( j, err := s.NewJob(
DurationJob( DurationJob(
100*time.Millisecond, 100*time.Millisecond,
@ -461,10 +458,9 @@ func TestScheduler_NewJob(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler() s := newTestScheduler(t)
require.NoError(t, err)
_, err = s.NewJob(tt.jd, tt.tsk, tt.opts...) _, err := s.NewJob(tt.jd, tt.tsk, tt.opts...)
require.NoError(t, err) require.NoError(t, err)
s.Start() s.Start()
@ -727,23 +723,21 @@ func TestScheduler_NewJobErrors(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler( s := newTestScheduler(t,
WithStopTimeout(time.Millisecond*50), WithStopTimeout(time.Millisecond*50),
) )
require.NoError(t, err)
_, err = s.NewJob(tt.jd, NewTask(func() {}), tt.opts...) _, err := s.NewJob(tt.jd, NewTask(func() {}), tt.opts...)
assert.ErrorIs(t, err, tt.err) assert.ErrorIs(t, err, tt.err)
require.NoError(t, s.Shutdown()) require.NoError(t, s.Shutdown())
}) })
t.Run(tt.name+" global", func(t *testing.T) { t.Run(tt.name+" global", func(t *testing.T) {
s, err := newTestScheduler( s := newTestScheduler(t,
WithStopTimeout(time.Millisecond*50), WithStopTimeout(time.Millisecond*50),
WithGlobalJobOptions(tt.opts...), WithGlobalJobOptions(tt.opts...),
) )
require.NoError(t, err)
_, err = s.NewJob(tt.jd, NewTask(func() {})) _, err := s.NewJob(tt.jd, NewTask(func() {}))
assert.ErrorIs(t, err, tt.err) assert.ErrorIs(t, err, tt.err)
require.NoError(t, s.Shutdown()) require.NoError(t, s.Shutdown())
}) })
@ -784,10 +778,9 @@ func TestScheduler_NewJobTask(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler() s := newTestScheduler(t)
require.NoError(t, err)
_, err = s.NewJob(DurationJob(time.Second), tt.tsk) _, err := s.NewJob(DurationJob(time.Second), tt.tsk)
assert.ErrorIs(t, err, tt.err) assert.ErrorIs(t, err, tt.err)
require.NoError(t, s.Shutdown()) require.NoError(t, s.Shutdown())
}) })
@ -845,7 +838,7 @@ func TestScheduler_WithOptionsErrors(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
_, err := newTestScheduler(tt.opt) _, err := NewScheduler(tt.opt)
assert.ErrorIs(t, err, tt.err) assert.ErrorIs(t, err, tt.err)
}) })
} }
@ -875,13 +868,12 @@ func TestScheduler_Singleton(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
jobRanCh := make(chan struct{}, 10) jobRanCh := make(chan struct{}, 10)
s, err := newTestScheduler( s := newTestScheduler(t,
WithStopTimeout(1*time.Second), WithStopTimeout(1*time.Second),
WithLocation(time.Local), WithLocation(time.Local),
) )
require.NoError(t, err)
_, err = s.NewJob( _, err := s.NewJob(
DurationJob( DurationJob(
tt.duration, tt.duration,
), ),
@ -948,16 +940,15 @@ func TestScheduler_LimitMode(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler( s := newTestScheduler(t,
WithLimitConcurrentJobs(tt.limit, tt.limitMode), WithLimitConcurrentJobs(tt.limit, tt.limitMode),
WithStopTimeout(2*time.Second), WithStopTimeout(2*time.Second),
) )
require.NoError(t, err)
jobRanCh := make(chan struct{}, 20) jobRanCh := make(chan struct{}, 20)
for i := 0; i < tt.numJobs; i++ { for i := 0; i < tt.numJobs; i++ {
_, err = s.NewJob( _, err := s.NewJob(
DurationJob(tt.duration), DurationJob(tt.duration),
NewTask(func() { NewTask(func() {
time.Sleep(tt.duration / 2) time.Sleep(tt.duration / 2)
@ -1024,17 +1015,16 @@ func TestScheduler_LimitModeAndSingleton(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler( s := newTestScheduler(t,
WithLimitConcurrentJobs(tt.limit, tt.limitMode), WithLimitConcurrentJobs(tt.limit, tt.limitMode),
WithStopTimeout(2*time.Second), WithStopTimeout(2*time.Second),
) )
require.NoError(t, err)
jobRanCh := make(chan int, 20) jobRanCh := make(chan int, 20)
for i := 0; i < tt.numJobs; i++ { for i := 0; i < tt.numJobs; i++ {
jobNum := i jobNum := i
_, err = s.NewJob( _, err := s.NewJob(
DurationJob(tt.duration), DurationJob(tt.duration),
NewTask(func() { NewTask(func() {
time.Sleep(tt.duration / 2) time.Sleep(tt.duration / 2)
@ -1149,15 +1139,14 @@ func TestScheduler_WithDistributed(t *testing.T) {
schedulersDone := make(chan struct{}, tt.count) schedulersDone := make(chan struct{}, tt.count)
for i := tt.count; i > 0; i-- { for i := tt.count; i > 0; i-- {
s, err := newTestScheduler( s := newTestScheduler(t,
tt.opt, tt.opt,
) )
require.NoError(t, err)
go func() { go func() {
s.Start() s.Start()
_, err = s.NewJob( _, err := s.NewJob(
DurationJob( DurationJob(
time.Second, time.Second,
), ),
@ -1229,8 +1218,7 @@ func TestScheduler_RemoveJob(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler() s := newTestScheduler(t)
require.NoError(t, err)
var id uuid.UUID var id uuid.UUID
if tt.addJob { if tt.addJob {
@ -1242,7 +1230,7 @@ func TestScheduler_RemoveJob(t *testing.T) {
} }
time.Sleep(50 * time.Millisecond) time.Sleep(50 * time.Millisecond)
err = s.RemoveJob(id) err := s.RemoveJob(id)
assert.ErrorIs(t, err, err) assert.ErrorIs(t, err, err)
require.NoError(t, s.Shutdown()) require.NoError(t, s.Shutdown())
}) })
@ -1310,9 +1298,8 @@ func TestScheduler_WithEventListeners(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
s, err := newTestScheduler() s := newTestScheduler(t)
require.NoError(t, err) _, err := s.NewJob(
_, err = s.NewJob(
DurationJob(time.Minute*10), DurationJob(time.Minute*10),
tt.tsk, tt.tsk,
WithStartAt( WithStartAt(
@ -1343,3 +1330,36 @@ func TestScheduler_WithEventListeners(t *testing.T) {
}) })
} }
} }
func TestScheduler_ManyJobs(t *testing.T) {
s := newTestScheduler(t)
jobsRan := make(chan struct{}, 20000)
for i := 1; i <= 1000; i++ {
_, err := s.NewJob(
DurationJob(
time.Millisecond*100,
),
NewTask(
func() {
jobsRan <- struct{}{}
},
),
WithStartAt(WithStartImmediately()),
)
require.NoError(t, err)
}
s.Start()
time.Sleep(1 * time.Second)
require.NoError(t, s.Shutdown())
close(jobsRan)
var count int
for range jobsRan {
count++
}
assert.GreaterOrEqual(t, count, 9900)
assert.LessOrEqual(t, count, 11000)
}