Documentation
¶
Overview ¶
Package cronlib provides a high-performance, thread-safe cron job scheduler for Go.
It allows scheduling jobs using standard cron syntax with seconds precision, as well as convenient macros like @every, @daily, etc.
Features ¶
- **Thread-Safe**: Safe for concurrent use from multiple goroutines.
- **High Performance**: Uses a bitmask-based parser for fast matching.
- **Seconds Precision**: Supports 6-field cron expressions (second, minute, hour, dom, month, dow).
- **Job Overlap Policies**: Control behavior when a previous job run is still active (Allow, Forbid, Replace).
- **Middleware/Wrappers**: Extensible job execution pipeline (logging, recovery, locking).
- **Persistence**: Interfaces for storing job state and execution history.
- **Distributed Locking**: Interfaces for cluster-wide job synchronization.
Syntax ¶
The cron expression format is a space-separated string with 6 fields:
Field name | Mandatory? | Allowed values | Allowed special characters ---------- | ---------- | -------------- | -------------------------- Seconds | Yes | 0-59 | * / , - Minutes | Yes | 0-59 | * / , - Hours | Yes | 0-23 | * / , - Day of month | Yes | 1-31 | * / , - Month | Yes | 1-12 | * / , - Day of week | Yes | 0-6 (Sun-Sat) | * / , -
Macros ¶
Pre-defined macros can be used in place of the cron expression:
@yearly (or @annually) Run once a year, midnight, Jan. 1st (0 0 0 1 1 *) @monthly Run once a month, midnight, first of month (0 0 0 1 * *) @weekly Run once a week, midnight between Sat/Sun (0 0 0 * * 0) @daily (or @midnight) Run once a day, midnight (0 0 0 * * *) @hourly Run once an hour, beginning of hour (0 0 * * * *) @every <duration> Run every <duration> (e.g. "@every 1h30m")
Usage Example ¶
package main
import (
"fmt"
"time"
"github.com/raythurman2386/cronlib"
)
func main() {
c := cronlib.NewCron()
// Run every 5 seconds
c.AddJob("*\0575 * * * * *", func() {
fmt.Println("Tick every 5s")
})
// Run every minute
c.AddJob("@every 1m", func() {
fmt.Println("Tick every 1m")
})
c.Start()
defer c.Stop()
// Block main thread
select {}
}
Index ¶
- type Cron
- func (c *Cron) AddJob(spec string, cmd func()) (string, error)
- func (c *Cron) AddJobWithOptions(spec string, cmd func(context.Context), opts JobOptions) (string, error)
- func (c *Cron) GetJobs() []JobStatus
- func (c *Cron) RemoveJob(id string)
- func (c *Cron) SetDistLock(l DistLock)
- func (c *Cron) SetJobStore(s JobStore)
- func (c *Cron) Start()
- func (c *Cron) Stop()
- type DistLock
- type Expression
- type Job
- type JobCmd
- type JobOptions
- type JobStatus
- type JobStore
- type JobWrapper
- type OverlapPolicy
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cron ¶
type Cron struct {
// contains filtered or unexported fields
}
Cron is the main scheduler engine. It manages a list of jobs and executes them according to their schedule. Methods on Cron are thread-safe.
func (*Cron) AddJob ¶
AddJob adds a new job to the scheduler. Returns the job ID and error if spec is invalid.
Example ¶
package main
import (
"fmt"
"github.com/raythurman2386/cronlib"
)
func main() {
c := cronlib.NewCron()
// Run every second
// Note: We use a channel to ensure the example output is deterministic
// for the purpose of this testable example.
done := make(chan struct{})
_, err := c.AddJob("* * * * * *", func() {
fmt.Println("Job executed")
close(done)
})
if err != nil {
fmt.Println("Error scheduling job:", err)
return
}
c.Start()
defer c.Stop()
<-done
}
Output: Job executed
func (*Cron) AddJobWithOptions ¶
func (c *Cron) AddJobWithOptions(spec string, cmd func(context.Context), opts JobOptions) (string, error)
AddJobWithOptions adds a new job with specific options.
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/raythurman2386/cronlib"
)
func main() {
c := cronlib.NewCron()
// Define a job with specific options
opts := cronlib.JobOptions{
Overlap: cronlib.OverlapForbid, // Skip if previous run is still active
}
_, err := c.AddJobWithOptions("*/5 * * * * *", func(ctx context.Context) {
fmt.Println("Job with context running")
}, opts)
if err != nil {
fmt.Println("Error:", err)
}
c.Start()
// Allow time for execution in a real app
time.Sleep(1 * time.Second)
c.Stop()
}
func (*Cron) SetDistLock ¶
SetDistLock configures the distributed lock.
func (*Cron) SetJobStore ¶
SetJobStore configures the persistence layer.
type DistLock ¶
type DistLock interface {
// Lock attempts to acquire a lock for the key. Returns true if acquired.
Lock(ctx context.Context, key string, ttl time.Duration) (bool, error)
// Unlock releases the lock.
Unlock(ctx context.Context, key string) error
}
DistLock defines distributed locking behavior.
type Expression ¶
type Expression struct {
// contains filtered or unexported fields
}
Expression represents the parsed cron expression using bitmasks.
func Parse ¶
func Parse(spec string) (Expression, error)
Parse parses a 6-field cron string or a macro into an Expression.
The standard format is:
second minute hour day-of-month month day-of-week
Supported macros:
@yearly, @annually (0 0 0 1 1 *) @monthly (0 0 0 1 * *) @weekly (0 0 0 * * 0) @daily, @midnight (0 0 0 * * *) @hourly (0 0 * * * *) @every <duration> (e.g., "@every 1h30m")
type Job ¶
type Job struct {
ID string
Spec string
Expr Expression
Cmd func(context.Context) error
// contains filtered or unexported fields
}
Job represents a scheduled task.
type JobOptions ¶
type JobOptions struct {
Overlap OverlapPolicy
Location *time.Location
Wrappers []JobWrapper
}
JobOptions configuration for a job.
type JobStatus ¶
type JobStatus struct {
ID string `json:"id"`
Expression string `json:"expression"`
NextRun time.Time `json:"next_run"`
LastRun time.Time `json:"last_run"`
Running bool `json:"running"`
}
JobStatus represents the state of a job.
type JobStore ¶
type JobStore interface {
GetLastRun(jobID string) (time.Time, error)
SetLastRun(jobID string, t time.Time) error
LogExecution(jobID string, start, end time.Time, success bool, out string) error
}
JobStore defines persistence for job state and history.
type JobWrapper ¶
JobWrapper decorates a job execution function. It allows injecting custom logic before and after the job runs (middleware).
func Chain ¶
func Chain(wrappers ...JobWrapper) JobWrapper
Chain combines multiple job wrappers into a single wrapper. Wrappers are executed in the order they are passed. Example: Chain(W1, W2) results in W1(W2(Job)).
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/raythurman2386/cronlib"
)
func main() {
// Define a custom wrapper that logs execution
loggingWrapper := func(next func(context.Context) error) func(context.Context) error {
return func(ctx context.Context) error {
fmt.Println("Starting job...")
err := next(ctx)
fmt.Println("Job finished")
return err
}
}
c := cronlib.NewCron()
opts := cronlib.JobOptions{
Wrappers: []cronlib.JobWrapper{loggingWrapper},
}
_, err := c.AddJobWithOptions("@every 1s", func(ctx context.Context) {
fmt.Println("Doing work")
}, opts)
if err != nil {
fmt.Println("Error:", err)
return
}
c.Start()
// Wait for one run
time.Sleep(1100 * time.Millisecond)
c.Stop()
}
func DelayIfStillRunning ¶
func DelayIfStillRunning() JobWrapper
DelayIfStillRunning ensures that job executions are sequential. If a job is triggered while a previous instance is running, it waits.
func Recover ¶
func Recover() JobWrapper
Recover creates a wrapper that catches panics and returns them as errors.
func SkipIfStillRunning ¶
func SkipIfStillRunning() JobWrapper
SkipIfStillRunning skips execution if the previous instance is still running. This is an alternative to the OverlapForbid policy, implemented as a wrapper.
type OverlapPolicy ¶
type OverlapPolicy int
OverlapPolicy defines how to handle job overlaps.
const ( // OverlapAllow allows multiple instances of the same job to run concurrently. OverlapAllow OverlapPolicy = iota // OverlapForbid skips execution if the previous instance is still running. OverlapForbid // OverlapReplace cancels the running instance and starts a new one. OverlapReplace )
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
distributed
command
|
|
|
fullstack
command
|
|
|
iot
command
|
|
|
overlap
command
|
|
|
persistence
command
|
|
|
pkg
|
|
|
dashboard
Package dashboard provides a simple web UI for monitoring cron jobs.
|
Package dashboard provides a simple web UI for monitoring cron jobs. |
|
lock/redis
Package redis provides a cronlib.DistLock implementation using Redis.
|
Package redis provides a cronlib.DistLock implementation using Redis. |
|
store/sqlite
Package sqlite provides a cronlib.JobStore implementation using SQLite.
|
Package sqlite provides a cronlib.JobStore implementation using SQLite. |