Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 57 additions & 3 deletions cron.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cron

import (
"context"
"fmt"
"sort"
"sync"
"time"
Expand All @@ -22,7 +23,7 @@ type Cron struct {
runningMu sync.Mutex
location *time.Location
parser ScheduleParser
nextID EntryID
nextID int
jobWaiter sync.WaitGroup
}

Expand All @@ -44,7 +45,7 @@ type Schedule interface {
}

// EntryID identifies an entry within a Cron instance
type EntryID int
type EntryID any

// Entry consists of a schedule and the func to execute on that schedule.
type Entry struct {
Expand Down Expand Up @@ -72,7 +73,16 @@ type Entry struct {
}

// Valid returns true if this is not the zero entry.
func (e Entry) Valid() bool { return e.ID != 0 }
func (e Entry) Valid() bool {
switch id := e.ID.(type) {
case int:
return id != 0
case string:
return id != ""
default:
return false
}
}

// byTime is a wrapper for sorting the entry array by time
// (with zero time at the end).
Expand Down Expand Up @@ -142,6 +152,24 @@ func (c *Cron) AddFunc(spec string, cmd func()) (EntryID, error) {
return c.AddJob(spec, FuncJob(cmd))
}

// AddFuncWithID AddFunc adds a func to the Cron to be run on the given schedule.
// The spec is parsed using the time zone of this Cron instance as the default.
// An opaque ID is returned that can be used to later remove it.
func (c *Cron) AddFuncWithID(id any, spec string, cmd func()) (EntryID, error) {
return c.AddJobWithID(id, spec, FuncJob(cmd))
}

// AddJobWithID AddJob adds a Job to the Cron to be run on the given schedule.
// The spec is parsed using the time zone of this Cron instance as the default.
// An opaque ID is returned that can be used to later remove it.
func (c *Cron) AddJobWithID(id any, spec string, cmd Job) (EntryID, error) {
schedule, err := c.parser.Parse(spec)
if err != nil {
return 0, err
}
return c.ScheduleWithID(id, schedule, cmd), nil
}

// AddJob adds a Job to the Cron to be run on the given schedule.
// The spec is parsed using the time zone of this Cron instance as the default.
// An opaque ID is returned that can be used to later remove it.
Expand All @@ -153,6 +181,32 @@ func (c *Cron) AddJob(spec string, cmd Job) (EntryID, error) {
return c.Schedule(schedule, cmd), nil
}

// ScheduleWithID Schedule adds a Job to the Cron to be run on the given schedule.
// The job is wrapped with the configured Chain.
func (c *Cron) ScheduleWithID(id any, schedule Schedule, cmd Job) EntryID {
c.runningMu.Lock()
defer c.runningMu.Unlock()

for _, entry := range c.entries {
if entry.ID == id {
return fmt.Errorf("an entry with this ID already exists: %d", id)
}
}

entry := &Entry{
ID: id,
Schedule: schedule,
WrappedJob: c.chain.Then(cmd),
Job: cmd,
}
if !c.running {
c.entries = append(c.entries, entry)
} else {
c.add <- entry
}
return entry.ID
}

// Schedule adds a Job to the Cron to be run on the given schedule.
// The job is wrapped with the configured Chain.
func (c *Cron) Schedule(schedule Schedule, cmd Job) EntryID {
Expand Down