Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: go-co-op/gocron
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.28.2
Choose a base ref
...
head repository: go-co-op/gocron
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.28.3
Choose a head ref
  • 5 commits
  • 6 files changed
  • 2 contributors

Commits on Jun 2, 2023

  1. upgrade to golangci lint 1.53.1 (#506)

    * upgrade to golangci lint 1.53
    
    * 1.53.0 -> 1.53.1
    
    * address lint findings
    JohnRoesler authored Jun 2, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2c3b43d View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7390192 View commit details

Commits on Jun 5, 2023

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f79bf56 View commit details

Commits on Jun 9, 2023

  1. chore: don't do codeql scanning on push for dependabot branches (#511)

    * ignore codeql for dependabot branches
    
    * Update .github/workflows/codeql-analysis.yml
    JohnRoesler authored Jun 9, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    272915a View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    fed28e8 View commit details
Showing with 36 additions and 10 deletions.
  1. +3 −0 .github/workflows/codeql-analysis.yml
  2. +2 −2 .github/workflows/go_test.yml
  3. +12 −2 executor.go
  4. +12 −0 job.go
  5. +1 −2 scheduler.go
  6. +6 −4 scheduler_test.go
3 changes: 3 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -14,7 +14,10 @@ name: "CodeQL"
on:
push:
branches: [ main ]
branches-ignore: "dependabot/**"
pull_request:
paths-ignore:
- '**.md'
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
4 changes: 2 additions & 2 deletions .github/workflows/go_test.yml
Original file line number Diff line number Diff line change
@@ -23,9 +23,9 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3.4.0
uses: golangci/golangci-lint-action@v3.5.0
with:
version: v1.51.2
version: v1.53.1
- name: Install Go
uses: actions/setup-go@v4
with:
14 changes: 12 additions & 2 deletions executor.go
Original file line number Diff line number Diff line change
@@ -80,13 +80,17 @@ func runJob(f jobFunction) {

func (jf *jobFunction) singletonRunner() {
jf.singletonRunnerOn.Store(true)
jf.singletonWgMu.Lock()
jf.singletonWg.Add(1)
jf.singletonWgMu.Unlock()
for {
select {
case <-jf.ctx.Done():
jf.singletonWg.Done()
jf.singletonRunnerOn.Store(false)
jf.singletonQueueMu.Lock()
jf.singletonQueue = make(chan struct{}, 1000)
jf.singletonQueueMu.Unlock()
jf.stopped.Store(false)
return
case <-jf.singletonQueue:
@@ -161,12 +165,14 @@ func (e *executor) runJob(f jobFunction) {
}
runJob(f)
case singletonMode:
e.singletonWgs.Store(f.singletonWg, struct{}{})
e.singletonWgs.Store(f.singletonWg, f.singletonWgMu)

if !f.singletonRunnerOn.Load() {
go f.singletonRunner()
}
f.singletonQueueMu.Lock()
f.singletonQueue <- struct{}{}
f.singletonQueueMu.Unlock()
}
}

@@ -239,8 +245,12 @@ func (e *executor) stop() {
e.wg.Wait()
if e.singletonWgs != nil {
e.singletonWgs.Range(func(key, value interface{}) bool {
if wg, ok := key.(*sync.WaitGroup); ok {
wg, wgOk := key.(*sync.WaitGroup)
mu, muOk := value.(*sync.Mutex)
if wgOk && muOk {
mu.Lock()
wg.Wait()
mu.Unlock()
}
return true
})
12 changes: 12 additions & 0 deletions job.go
Original file line number Diff line number Diff line change
@@ -49,6 +49,7 @@ type jobFunction struct {
jobName string // key of the distributed lock
funcName string // the name of the function - e.g. main.func1
runConfig runConfig // configuration for how many times to run the job
singletonQueueMu *sync.Mutex // mutex for singletonQueue
singletonQueue chan struct{} // queues jobs for the singleton runner to handle
singletonRunnerOn *atomic.Bool // whether the runner function for singleton is running
ctx context.Context // for cancellation
@@ -57,6 +58,7 @@ type jobFunction struct {
runStartCount *atomic.Int64 // number of times the job was started
runFinishCount *atomic.Int64 // number of times the job was finished
singletonWg *sync.WaitGroup // used by singleton runner
singletonWgMu *sync.Mutex // use to protect the singletonWg
stopped *atomic.Bool // tracks whether the job is currently stopped
jobFuncNextRun time.Time // the next time the job is scheduled to run
}
@@ -80,12 +82,14 @@ func (jf *jobFunction) copy() jobFunction {
jobName: jf.jobName,
runConfig: jf.runConfig,
singletonQueue: jf.singletonQueue,
singletonQueueMu: jf.singletonQueueMu,
ctx: jf.ctx,
cancel: jf.cancel,
isRunning: jf.isRunning,
runStartCount: jf.runStartCount,
runFinishCount: jf.runFinishCount,
singletonWg: jf.singletonWg,
singletonWgMu: jf.singletonWgMu,
singletonRunnerOn: jf.singletonRunnerOn,
stopped: jf.stopped,
jobFuncNextRun: jf.jobFuncNextRun,
@@ -420,8 +424,16 @@ func (j *Job) SingletonMode() {
j.mu.Lock()
defer j.mu.Unlock()
j.runConfig.mode = singletonMode

j.jobFunction.singletonWgMu = &sync.Mutex{}
j.jobFunction.singletonWgMu.Lock()
j.jobFunction.singletonWg = &sync.WaitGroup{}
j.jobFunction.singletonWgMu.Unlock()

j.jobFunction.singletonQueueMu = &sync.Mutex{}
j.jobFunction.singletonQueueMu.Lock()
j.jobFunction.singletonQueue = make(chan struct{}, 100)
j.jobFunction.singletonQueueMu.Unlock()
}

// shouldRun evaluates if this job should run again
3 changes: 1 addition & 2 deletions scheduler.go
Original file line number Diff line number Diff line change
@@ -1175,9 +1175,8 @@ func (s *Scheduler) Months(daysOfTheMonth ...int) *Scheduler {
if _, ok := repeatMap[dayOfMonth]; ok {
job.error = wrapOrError(job.error, ErrInvalidDaysOfMonthDuplicateValue)
break
} else {
repeatMap[dayOfMonth]++
}
repeatMap[dayOfMonth]++
}
}
if job.daysOfTheMonth == nil {
10 changes: 6 additions & 4 deletions scheduler_test.go
Original file line number Diff line number Diff line change
@@ -23,8 +23,8 @@ func (f fakeTime) Now(loc *time.Location) time.Time {
return f.onNow(loc)
}

func (f fakeTime) Unix(i int64, i2 int64) time.Time {
panic("implement me")
func (f fakeTime) Unix(sec int64, nsec int64) time.Time {
return time.Unix(sec, nsec)
}

func (f fakeTime) Sleep(d time.Duration) {
@@ -148,7 +148,8 @@ func TestScheduler_Every(t *testing.T) {
}
}
s.Stop()
assert.Equal(t, 2, counter)
assert.GreaterOrEqual(t, counter, 2)
assert.LessOrEqual(t, counter, 3)
})

t.Run("string duration", func(t *testing.T) {
@@ -2355,7 +2356,8 @@ func TestScheduler_CheckCalculateDaysOfMonth(t *testing.T) {

func TestScheduler_CheckSetBehaviourBeforeJobCreated(t *testing.T) {
s := NewScheduler(time.UTC)
s.Month(1, 2).Every(1).Do(func() {})
_, err := s.Month(1, 2).Every(1).Do(func() {})
assert.NoError(t, err)
}

func TestScheduler_MonthLastDayAtTime(t *testing.T) {