cron

package module
v0.0.0-...-2db3d1b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2025 License: MIT Imports: 21 Imported by: 0

README

Changes:
Jobs has a context
Jobs recover panic by default
Jobs can have a description (label)
Jobs ID are string and can have user specified ID
Can have a job that only run once using cron.Once
Can change the *time.Location while running
Do not sort all entries at every iteration
Use Heap data structure to store entries
Can ask the cron object if a job is currently running with isRunning := c.IsRunning(entryID)
Tests runs in under a second (instead of over a minute)
Comes with a complete admin web interface built-in

package main

import (
	"context"
	"errors"
	"fmt"
	"github.com/soluty/cron"
	"github.com/soluty/cron/httpManagement"
	"log"
	"net/http"
	"os"
	"time"
)

type SomeJob struct{}

// Run implements the Job interface for SomeJob
func (s SomeJob) Run(context.Context, *cron.Cron, cron.Entry) error {
	fmt.Println("Some job")
	return nil
}

func main() {
	appCtx := context.Background()

	l := log.New(os.Stdout, "", log.LstdFlags)

	c := cron.New(
		cron.WithParser(cron.SecondParser),
		cron.WithContext(appCtx), // Can provide a custom context
		cron.WithLogger(l),       // Can provide a custom logger
	)

	// A simple function can be used as a job
	_, _ = c.AddJob("* * * * * *", func() {
		fmt.Println("hello world")
	})

	// If your function returns an error, it will be logged by the cron logger
	_, _ = c.AddJob("* * * * * *", func() error {
		return errors.New("this error will be logged by the cron logger")
	})

	// You can give a description to your jobs using the cron.Label helper
	// The label will be part of the log if the job returns an error
	_, _ = c.AddJob("* * * * * *", func() error {
		return errors.New("this error will be logged by the cron logger")
	}, cron.Label("some description"))

	// A job can also receive a context if you want to handle graceful shutdown
	_, _ = c.AddJob("* * * * * *", func(ctx context.Context) {
		// ...
	})

	// This is also valid
	_, _ = c.AddJob("* * * * * *", func(ctx context.Context) error {
		return nil
	})

	// WithTimeout will ensure that the context get cancelled after the given duration
	_, _ = c.AddJob("*/3 * * * * *", cron.WithTimeout(2*time.Second, func(ctx context.Context) {
		select {
		case <-time.After(time.Minute):
		case <-ctx.Done():
			return
		}
	}))

	// This is also valid
	_, _ = c.AddJob("*/3 * * * * *", cron.WithTimeout(2*time.Second, func(ctx context.Context) error {
		select {
		case <-time.After(time.Minute):
		case <-ctx.Done():
			return ctx.Err()
		}
		return nil
	}))

	// Anything that implements the Job interface can be used for job
	// Or any of:
	// Run()
	// Run() error
	// Run(context.Context)
	// Run(context.Context) error
	// Run(cron.EntryID)
	// Run(cron.EntryID) error
	// Run(cron.Entry)
	// Run(cron.Entry) error
	// Run(*cron.Cron)
	// Run(*cron.Cron) error
	// Run(context.Context, cron.EntryID)
	// Run(context.Context, cron.EntryID) error
	// Run(context.Context, cron.Entry)
	// Run(context.Context, cron.Entry) error
	// Run(context.Context, *cron.Cron)
	// Run(context.Context, *cron.Cron) error
	// Run(*cron.Cron, cron.EntryID)
	// Run(*cron.Cron, cron.EntryID) error
	// Run(*cron.Cron, cron.Entry)
	// Run(*cron.Cron, cron.Entry) error
	// Run(context.Context, *cron.Cron, cron.EntryID)
	// Run(context.Context, *cron.Cron, cron.EntryID) error
	// Run(context.Context, *cron.Cron, cron.Entry)
	// Run(context.Context, *cron.Cron, cron.Entry) error
	_, _ = c.AddJob("* * * * * *", SomeJob{})

	// When using cron.Once, the job will remove itself from the cron entries
	// after being executed once
	_, _ = c.AddJob("* * * * * *", cron.Once(func() {
		fmt.Println("Will only be executed once")
	}))

	// When using cron.N, the job will remove itself from the cron entries
	// after being executed "n" times
	_, _ = c.AddJob("* * * * * *", cron.N(2, func() {
		fmt.Println("Will be executed 2 times")
	}))

	// cron.SkipIfStillRunning will ensure that the job is skipped if a previous
	// invocation is still running
	_, _ = c.AddJob("* * * * * *", cron.SkipIfStillRunning(func() {
		fmt.Println("Slow job")
		time.Sleep(3 * time.Second)
	}))

	// You can use cron.Chain to chain wrappers to your job
	_, _ = c.AddJob("* * * * * *", cron.Chain(func() {
		fmt.Println("job with chained wrappers")
	}, cron.TimeoutWrapper(time.Second), cron.Once))

	// Jitter adds some random delay before running the job
	_, _ = c.AddJob("0 */5 * * * *", cron.WithJitter(time.Minute, func() {
		fmt.Println("Runs every 5min, but wait 0-1 minute before starting")
	}))

	// This job is disabled by default
	disabledID, _ := c.AddJob("* * * * * *", func() {
		fmt.Println("this job is disabled by default")
	}, cron.Disabled)

	// Job can be enabled/disabled using their ID
	c.Enable(disabledID)
	c.Disable(disabledID)

	// You can specify the ID to use for a job
	_, _ = c.AddJob("* * * * * *", func(id cron.EntryID) {
		fmt.Printf("this job has a custom ID: %s\n", id)
	}, cron.WithID("my-job-id"))

	// You can run a job as soon as the cron is started with cron.RunOnStart
	_, _ = c.AddJob("*/10 * * * * *", func() {
		fmt.Println("this job runs as soon as cron is started, then at every 10th seconds", time.Now())
	}, cron.RunOnStart)

	// This is an example of how you can get the time
	// the job was scheduled to run at
	_, _ = c.AddJob("*/5 * * * * *", func(entry cron.Entry) {
		fmt.Println(entry.Prev.UnixNano(), time.Now().UnixNano())
	})

	c.Start()

	// This library comes with a complete web interface administration tool (optional)
	mux := httpManagement.GetMux(c)
	if err := http.ListenAndServe(":8080", mux); err != nil {
		log.Fatal(err)
	}
}

go test -v ./...
go clean -testcache && go test -race ./...

Documentation

Overview

Package cron implements a cron spec parser and job runner.

Usage

Callers may register Funcs to be invoked on a given schedule. Cron will run them in their own goroutines.

c := cron.New()
c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") })
c.AddFunc("@hourly",      func() { fmt.Println("Every hour") })
c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") })
c.Start()
..
// Funcs are invoked in their own goroutine, asynchronously.
...
// Funcs may also be added to a running Cron
c.AddFunc("@daily", func() { fmt.Println("Every day") })
..
// Inspect the cron job entries' next and previous run times.
inspect(c.Entries())
..
c.Stop()  // Stop the scheduler (does not stop any jobs already running).

CRON Expression Format

A cron expression represents a set of times, using 6 space-separated 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 or JAN-DEC | * / , -
Day of week  | Yes        | 0-6 or SUN-SAT  | * / , - ?

Note: Month and Day-of-week field values are case insensitive. "SUN", "Sun", and "sun" are equally accepted.

Special Characters

Asterisk ( * )

The asterisk indicates that the cron expression will match for all values of the field; e.g., using an asterisk in the 5th field (month) would indicate every month.

Slash ( / )

Slashes are used to describe increments of ranges. For example 3-59/15 in the 1st field (minutes) would indicate the 3rd minute of the hour and every 15 minutes thereafter. The form "*\/..." is equivalent to the form "first-last/...", that is, an increment over the largest possible range of the field. The form "N/..." is accepted as meaning "N-MAX/...", that is, starting at N, use the increment until the end of that specific range. It does not wrap around.

Comma ( , )

Commas are used to separate items of a list. For example, using "MON,WED,FRI" in the 5th field (day of week) would mean Mondays, Wednesdays and Fridays.

Hyphen ( - )

Hyphens are used to define ranges. For example, 9-17 would indicate every hour between 9am and 5pm inclusive.

Question mark ( ? )

Question mark may be used instead of '*' for leaving either day-of-month or day-of-week blank.

Predefined schedules

You may use one of several pre-defined schedules in place of a cron expression.

Entry                  | Description                                | Equivalent To
-----                  | -----------                                | -------------
@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 * * * *

Intervals

You may also schedule a job to execute at fixed intervals, starting at the time it's added or cron is run. This is supported by formatting the cron spec like this:

@every <duration>

where "duration" is a string accepted by time.ParseDuration (http://golang.org/pkg/time/#ParseDuration).

For example, "@every 1h30m10s" would indicate a schedule that activates after 1 hour, 30 minutes, 10 seconds, and then every interval after that.

Note: The interval does not take the job runtime into account. For example, if a job takes 3 minutes to run, and it is scheduled to run every 5 minutes, it will have only 2 minutes of idle time between each run.

Time zones

All interpretation and scheduling is done in the machine's local time zone (as provided by the Go time package (http://www.golang.org/pkg/time).

Be aware that jobs scheduled during daylight-savings leap-ahead transitions will not be run!

Thread safety

Since the Cron service runs concurrently with the calling code, some amount of care must be taken to ensure proper synchronization.

All cron methods are designed to be correctly synchronized as long as the caller ensures that invocations have a clear happens-before ordering between them.

Implementation

Cron entries are stored in an array, sorted by their next activation time. Cron sleeps until the next job is due to be run.

Upon waking:

  • it runs each entry that is active on that second
  • it calculates the next run times for the jobs that were run
  • it re-sorts the array of entries by next activation time.
  • it goes to sleep until the soonest job.

Index

Constants

This section is empty.

Variables

View Source
var ErrEntryNotFound = errors.New("entry not found")

ErrEntryNotFound ...

View Source
var ErrIDAlreadyUsed = errors.New("id already used")

ErrIDAlreadyUsed ...

View Source
var ErrJobAlreadyRunning = errors.New("job already running")

ErrJobAlreadyRunning ...

View Source
var ErrRunNotFound = errors.New("run not found")

ErrRunNotFound ...

View Source
var ErrUnsupportedJobType = errors.New("unsupported job type")

ErrUnsupportedJobType ...

Functions

func Disabled

func Disabled(_ *Cron, entry *Entry)

func Label

func Label(label string) func(*Cron, *Entry)

func RunOnStart

func RunOnStart(c *Cron, entry *Entry)

func WithID

func WithID(id EntryID) func(*Cron, *Entry)

func WithNext

func WithNext(next time.Time) func(*Cron, *Entry)

Types

type Config

type Config struct {
	Ctx                  context.Context
	Location             *time.Location
	Clock                clockwork.Clock
	Logger               *log.Logger
	Parser               ScheduleParser
	IDFactory            EntryIDFactory
	KeepCompletedRunsDur *time.Duration
}

Config ...

type ConstantDelaySchedule

type ConstantDelaySchedule struct {
	Delay time.Duration
}

ConstantDelaySchedule represents a simple recurring duty cycle, e.g. "Every 5 minutes". It does not support jobs more frequent than once a second.

func Every

func Every(duration time.Duration) ConstantDelaySchedule

Every returns a crontab Schedule that activates once every duration. Delays of less than a second are not supported (will round up to 1 second). Any fields less than a Second are truncated.

func (ConstantDelaySchedule) Next

Next returns the next time this should be run. This rounds so that the next activation time will be on the second.

type Cron

type Cron struct {
	// contains filtered or unexported fields
}

Cron keeps track of any number of entries, invoking the associated func as specified by the schedule. It may be started, stopped, and the entries may be inspected while running.

func New

func New(opts ...Option) *Cron

New returns a new Cron job runner

func (*Cron) AddEntry

func (c *Cron) AddEntry(entry Entry, opts ...EntryOption) (EntryID, error)

AddEntry ...

func (*Cron) AddJob

func (c *Cron) AddJob(spec string, job IntoJob, opts ...EntryOption) (EntryID, error)

AddJob adds a Job to the Cron to be run on the given schedule.

func (*Cron) AddJob1

func (c *Cron) AddJob1(spec string, job Job, opts ...EntryOption) (EntryID, error)

AddJob1 adds a Job to the Cron to be run on the given schedule.

func (*Cron) CancelRun

func (c *Cron) CancelRun(entryID EntryID, runID RunID) error

CancelRun ...

func (*Cron) CompletedJobRunsFor

func (c *Cron) CompletedJobRunsFor(entryID EntryID) ([]JobRun, error)

CompletedJobRunsFor ...

func (*Cron) Disable

func (c *Cron) Disable(id EntryID)

Disable ...

func (*Cron) Enable

func (c *Cron) Enable(id EntryID)

Enable ...

func (*Cron) Entries

func (c *Cron) Entries() []Entry

Entries returns a snapshot of the cron entries.

func (*Cron) Entry

func (c *Cron) Entry(id EntryID) (Entry, error)

Entry returns a snapshot of the given entry, or nil if it couldn't be found.

func (*Cron) GetCleanupTS

func (c *Cron) GetCleanupTS() time.Time

GetCleanupTS ...

func (*Cron) GetNextTime

func (c *Cron) GetNextTime() time.Time

GetNextTime returns the next time a job is scheduled to be executed If no job is scheduled to be executed, the Zero time is returned

func (*Cron) GetRun

func (c *Cron) GetRun(entryID EntryID, runID RunID) (JobRun, error)

GetRun ...

func (*Cron) IsRunning

func (c *Cron) IsRunning(id EntryID) bool

IsRunning either or not a specific job is currently running

func (*Cron) JobRunCompletedCh

func (c *Cron) JobRunCompletedCh() <-chan *jobRunStruct

JobRunCompletedCh ...

func (*Cron) JobRunCreatedCh

func (c *Cron) JobRunCreatedCh() <-chan *jobRunStruct

JobRunCreatedCh ...

func (*Cron) Location

func (c *Cron) Location() *time.Location

Location gets the time zone location

func (*Cron) Remove

func (c *Cron) Remove(id EntryID)

Remove an entry from being run in the future.

func (*Cron) Run

func (c *Cron) Run() (started bool)

Run the cron scheduler, or no-op if already running.

func (*Cron) RunNow

func (c *Cron) RunNow(id EntryID) error

RunNow allows the user to run a specific job now

func (*Cron) RunningJobs

func (c *Cron) RunningJobs() []JobRun

RunningJobs ...

func (*Cron) RunningJobsFor

func (c *Cron) RunningJobsFor(entryID EntryID) ([]JobRun, error)

RunningJobsFor ...

func (*Cron) Schedule

func (c *Cron) Schedule(schedule Schedule, job Job, opts ...EntryOption) (EntryID, error)

Schedule adds a Job to the Cron to be run on the given schedule.

func (*Cron) SetLocation

func (c *Cron) SetLocation(newLoc *time.Location)

SetLocation sets a new location to use. Re-set the "Next" values for all entries. Re-sort entries and run due entries.

func (*Cron) Start

func (c *Cron) Start() (started bool)

Start the cron scheduler in its own go-routine, or no-op if already started.

func (*Cron) Stop

func (c *Cron) Stop() <-chan struct{}

Stop stops the cron scheduler if it is running; otherwise it does nothing. A context is returned so the caller can wait for running jobs to complete.

func (*Cron) Sub

func (c *Cron) Sub(id EntryID) *pubsub.Sub[EntryID, JobEvent]

Sub subscribes to Job events

func (*Cron) UpdateLabel

func (c *Cron) UpdateLabel(id EntryID, label string)

UpdateLabel ...

func (*Cron) UpdateSchedule

func (c *Cron) UpdateSchedule(id EntryID, schedule Schedule) error

UpdateSchedule ...

func (*Cron) UpdateScheduleWithSpec

func (c *Cron) UpdateScheduleWithSpec(id EntryID, spec string) error

UpdateScheduleWithSpec ...

type Entry

type Entry struct {
	ID   EntryID
	Spec *string
	// The schedule on which this job should be run.
	Schedule Schedule
	// The next time the job will run. This is the zero time if Cron has not been started or this entry's schedule is unsatisfiable
	Next time.Time
	// The last time this job was run. This is the zero time if the job has never been run.
	Prev time.Time
	// Label to describe the job
	Label string
	// Either or not the job is currently active
	Active bool
	// contains filtered or unexported fields
}

Entry consists of a schedule and the func to execute on that schedule.

func (Entry) Job

func (e Entry) Job() any

Job returns the original job as it was before it was wrapped by the cron library

type EntryHeap

type EntryHeap []*Entry

func (*EntryHeap) Len

func (h *EntryHeap) Len() int

func (*EntryHeap) Less

func (h *EntryHeap) Less(i, j int) bool

func (*EntryHeap) Peek

func (h *EntryHeap) Peek() *Entry

func (*EntryHeap) Pop

func (h *EntryHeap) Pop() (v any)

func (*EntryHeap) Push

func (h *EntryHeap) Push(v any)

func (*EntryHeap) Swap

func (h *EntryHeap) Swap(i, j int)

type EntryID

type EntryID string

EntryID ...

type EntryIDFactory

type EntryIDFactory interface {
	Next() EntryID
}

func UUIDEntryIDFactory

func UUIDEntryIDFactory() EntryIDFactory

UUIDEntryIDFactory generate and format UUID V4

type EntryOption

type EntryOption func(*Cron, *Entry)

type FuncEntryIDFactory

type FuncEntryIDFactory func() EntryID

func (FuncEntryIDFactory) Next

func (f FuncEntryIDFactory) Next() EntryID

type FuncJob

type FuncJob func(context.Context, *Cron, Entry) error

FuncJob is a wrapper that turns a func() into a cron.Job

func (FuncJob) Run

func (f FuncJob) Run(ctx context.Context, c *Cron, e Entry) error

type IntoJob

type IntoJob any

type Job

type Job interface {
	Run(context.Context, *Cron, Entry) error
}

Job is an interface for submitted cron jobs.

func Chain

func Chain(j IntoJob, wrappers ...JobWrapper) Job

Chain `Chain(j, w1, w2, w3)` -> `w3(w2(w1(j)))`

func J

func J(v IntoJob) Job

J is a helper to turn a IntoJob into a Job Any of these functions, or anything that have a "Run" method with one of these signatures can be casted into a Job. func() func() error func(context.Context) func(context.Context) error func(cron.EntryID) func(cron.EntryID) error func(cron.Entry) func(cron.Entry) error func(*cron.Cron) func(*cron.Cron) error func(context.Context, cron.EntryID) func(context.Context, cron.EntryID) error func(context.Context, cron.Entry) func(context.Context, cron.Entry) error func(context.Context, *cron.Cron) func(context.Context, *cron.Cron) error func(*cron.Cron, cron.EntryID) func(*cron.Cron, cron.EntryID) error func(*cron.Cron, cron.Entry) func(*cron.Cron, cron.Entry) error func(context.Context, *cron.Cron, cron.EntryID) func(context.Context, *cron.Cron, cron.EntryID) error func(context.Context, *cron.Cron, cron.Entry) func(context.Context, *cron.Cron, cron.Entry) error

func N

func N(n int, j IntoJob) Job

N runs a job "n" times

func Once

func Once(job IntoJob) Job

func SkipIfStillRunning

func SkipIfStillRunning(j IntoJob) Job

SkipIfStillRunning skips an invocation of the Job if a previous invocation is still running.

func WithDeadline

func WithDeadline(deadline time.Time, job IntoJob) Job

func WithJitter

func WithJitter(duration time.Duration, job IntoJob) Job

WithJitter add some random delay before running the job

func WithTimeout

func WithTimeout(d time.Duration, job IntoJob) Job

WithTimeout ... `_, _ = cron.AddJob("* * * * * *", cron.WithTimeout(time.Second, func(ctx context.Context) { ... }))`

type Job1

type Job1 interface{ Run() }

type Job1Wrapper

type Job1Wrapper struct{ Job1 }

func (*Job1Wrapper) Run

type Job2

type Job2 interface{ Run(context.Context) }

type Job2Wrapper

type Job2Wrapper struct{ Job2 }

func (*Job2Wrapper) Run

func (j *Job2Wrapper) Run(ctx context.Context, _ *Cron, _ Entry) error

type Job3

type Job3 interface{ Run(EntryID) }

type Job3Wrapper

type Job3Wrapper struct{ Job3 }

func (*Job3Wrapper) Run

func (j *Job3Wrapper) Run(_ context.Context, _ *Cron, e Entry) error

type Job4

type Job4 interface {
	Run(context.Context, EntryID)
}

type Job4Wrapper

type Job4Wrapper struct{ Job4 }

func (*Job4Wrapper) Run

func (j *Job4Wrapper) Run(ctx context.Context, _ *Cron, e Entry) error

type Job5

type Job5 interface{ Run() error }

type Job5Wrapper

type Job5Wrapper struct{ Job5 }

func (*Job5Wrapper) Run

type Job6

type Job6 interface{ Run(context.Context) error }

type Job6Wrapper

type Job6Wrapper struct{ Job6 }

func (*Job6Wrapper) Run

func (j *Job6Wrapper) Run(ctx context.Context, _ *Cron, _ Entry) error

type Job7

type Job7 interface{ Run(EntryID) error }

type Job7Wrapper

type Job7Wrapper struct{ Job7 }

func (*Job7Wrapper) Run

func (j *Job7Wrapper) Run(_ context.Context, _ *Cron, e Entry) error

type Job8

type Job8 interface {
	Run(context.Context, EntryID) error
}

type Job8Wrapper

type Job8Wrapper struct{ Job8 }

func (*Job8Wrapper) Run

func (j *Job8Wrapper) Run(ctx context.Context, _ *Cron, e Entry) error

type Job9

type Job9 interface{ Run(*Cron) }

type Job9Wrapper

type Job9Wrapper struct{ Job9 }

func (*Job9Wrapper) Run

func (j *Job9Wrapper) Run(_ context.Context, cron *Cron, _ Entry) error

type Job10

type Job10 interface{ Run(*Cron) error }

type Job10Wrapper

type Job10Wrapper struct{ Job10 }

func (*Job10Wrapper) Run

func (j *Job10Wrapper) Run(_ context.Context, cron *Cron, _ Entry) error

type Job11

type Job11 interface{ Run(context.Context, *Cron) }

type Job11Wrapper

type Job11Wrapper struct{ Job11 }

func (*Job11Wrapper) Run

func (j *Job11Wrapper) Run(ctx context.Context, cron *Cron, _ Entry) error

type Job12

type Job12 interface {
	Run(context.Context, *Cron) error
}

type Job12Wrapper

type Job12Wrapper struct{ Job12 }

func (*Job12Wrapper) Run

func (j *Job12Wrapper) Run(ctx context.Context, cron *Cron, _ Entry) error

type Job13

type Job13 interface{ Run(*Cron, EntryID) }

type Job13Wrapper

type Job13Wrapper struct{ Job13 }

func (*Job13Wrapper) Run

func (j *Job13Wrapper) Run(_ context.Context, cron *Cron, e Entry) error

type Job14

type Job14 interface{ Run(*Cron, EntryID) error }

type Job14Wrapper

type Job14Wrapper struct{ Job14 }

func (*Job14Wrapper) Run

func (j *Job14Wrapper) Run(_ context.Context, cron *Cron, e Entry) error

type Job15

type Job15 interface {
	Run(context.Context, *Cron, EntryID)
}

type Job15Wrapper

type Job15Wrapper struct{ Job15 }

func (*Job15Wrapper) Run

func (j *Job15Wrapper) Run(ctx context.Context, cron *Cron, e Entry) error

type Job16

type Job16 interface {
	Run(context.Context, *Cron, EntryID) error
}

type Job16Wrapper

type Job16Wrapper struct{ Job16 }

func (*Job16Wrapper) Run

func (j *Job16Wrapper) Run(ctx context.Context, cron *Cron, e Entry) error

type Job17

type Job17 interface{ Run(Entry) }

type Job17Wrapper

type Job17Wrapper struct{ Job17 }

func (*Job17Wrapper) Run

func (j *Job17Wrapper) Run(_ context.Context, _ *Cron, e Entry) error

type Job18

type Job18 interface{ Run(Entry) error }

type Job18Wrapper

type Job18Wrapper struct{ Job18 }

func (*Job18Wrapper) Run

func (j *Job18Wrapper) Run(_ context.Context, _ *Cron, e Entry) error

type Job19

type Job19 interface{ Run(context.Context, Entry) }

type Job19Wrapper

type Job19Wrapper struct{ Job19 }

func (*Job19Wrapper) Run

func (j *Job19Wrapper) Run(ctx context.Context, _ *Cron, e Entry) error

type Job20

type Job20 interface {
	Run(context.Context, Entry) error
}

type Job20Wrapper

type Job20Wrapper struct{ Job20 }

func (*Job20Wrapper) Run

func (j *Job20Wrapper) Run(ctx context.Context, _ *Cron, e Entry) error

type Job21

type Job21 interface{ Run(*Cron, Entry) }

type Job21Wrapper

type Job21Wrapper struct{ Job21 }

func (*Job21Wrapper) Run

func (j *Job21Wrapper) Run(_ context.Context, c *Cron, e Entry) error

type Job22

type Job22 interface{ Run(*Cron, Entry) error }

type Job22Wrapper

type Job22Wrapper struct{ Job22 }

func (*Job22Wrapper) Run

func (j *Job22Wrapper) Run(_ context.Context, c *Cron, e Entry) error

type Job23

type Job23 interface {
	Run(context.Context, *Cron, Entry)
}

type Job23Wrapper

type Job23Wrapper struct{ Job23 }

func (*Job23Wrapper) Run

func (j *Job23Wrapper) Run(ctx context.Context, c *Cron, e Entry) error

type JobEvent

type JobEvent struct {
	Typ       JobEventType
	JobRun    JobRun
	CreatedAt time.Time
}

func NewJobEvent

func NewJobEvent(typ JobEventType, jobRun *jobRunStruct) JobEvent

type JobEventType

type JobEventType int
const (
	Start JobEventType = iota + 1
	Completed
	CompletedNoErr
	CompletedErr
	CompletedPanic
)

func (JobEventType) String

func (e JobEventType) String() string

type JobRun

type JobRun struct {
	RunID       RunID
	Entry       Entry
	CreatedAt   time.Time
	StartedAt   *time.Time
	CompletedAt *time.Time
	Events      []JobEvent
	Error       error
	Panic       bool
}

type JobWrapper

type JobWrapper func(IntoJob) Job

func DeadlineWrapper

func DeadlineWrapper(deadline time.Time) JobWrapper

func JitterWrapper

func JitterWrapper(duration time.Duration) JobWrapper

JitterWrapper add some random delay before running the job

func NWrapper

func NWrapper(n int) JobWrapper

func TimeoutWrapper

func TimeoutWrapper(duration time.Duration) JobWrapper

TimeoutWrapper automatically cancel the job context after a given duration

type Option

type Option func(*Config)

Option represents a modification to the default behavior of a Cron.

func WithClock

func WithClock(clock clockwork.Clock) Option

WithClock ...

func WithContext

func WithContext(ctx context.Context) Option

WithContext ...

func WithIDFactory

func WithIDFactory(idFactory EntryIDFactory) Option

WithIDFactory ...

func WithLocation

func WithLocation(loc *time.Location) Option

WithLocation overrides the timezone of the cron instance.

func WithLogger

func WithLogger(logger *log.Logger) Option

WithLogger ...

func WithParser

func WithParser(p ScheduleParser) Option

WithParser overrides the parser used for interpreting job schedules.

type ParseOption

type ParseOption int

Configuration options for creating a parser. Most options specify which fields should be included, while others enable features. If a field is not included the parser will assume a default value. These options do not change the order fields are parse in.

const (
	Second         ParseOption = 1 << iota // Seconds field, default 0
	SecondOptional                         // Optional seconds field, default 0
	Minute                                 // Minutes field, default 0
	Hour                                   // Hours field, default 0
	Dom                                    // Day of month field, default *
	Month                                  // Month field, default *
	Dow                                    // Day of week field, default *
	DowOptional                            // Optional day of week field, default *
	Descriptor                             // Allow descriptors such as @monthly, @weekly, etc.
)

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

A custom Parser that can be configured.

func NewParser

func NewParser(options ParseOption) Parser

NewParser creates a Parser with custom options.

It panics if more than one Optional is given, since it would be impossible to correctly infer which optional is provided or missing in general.

Examples

// Standard parser without descriptors
specParser := NewParser(Minute | Hour | Dom | Month | Dow)
sched, err := specParser.Parse("0 0 15 */3 *")

// Same as above, just excludes time fields
specParser := NewParser(Dom | Month | Dow)
sched, err := specParser.Parse("15 */3 *")

// Same as above, just makes Dow optional
specParser := NewParser(Dom | Month | DowOptional)
sched, err := specParser.Parse("15 */3")

func (Parser) Parse

func (p Parser) Parse(spec string) (Schedule, error)

Parse returns a new crontab schedule representing the given spec. It returns a descriptive error if the spec is not valid. It accepts crontab specs and features configured by NewParser.

type RunID

type RunID string

RunID ...

type Schedule

type Schedule interface {
	// Next return the next activation time, later than the given time.
	// Next is invoked initially, and then each time the job is run.
	Next(time.Time) time.Time
}

The Schedule describes a job's duty cycle.

func ParseStandard

func ParseStandard(standardSpec string) (Schedule, error)

ParseStandard returns a new crontab schedule representing the given standardSpec (https://en.wikipedia.org/wiki/Cron). It requires 5 entries representing: minute, hour, day of month, month and day of week, in that order. It returns a descriptive error if the spec is not valid.

It accepts

  • Standard crontab specs, e.g. "* * * * ?"
  • Descriptors, e.g. "@midnight", "@every 1h30m"

type ScheduleParser

type ScheduleParser interface {
	Parse(spec string) (Schedule, error)
}

ScheduleParser is an interface for schedule spec parsers that return a Schedule

type SpecSchedule

type SpecSchedule struct {
	Second, Minute, Hour, Dom, Month, Dow uint64

	// Override location for this schedule.
	Location *time.Location
}

SpecSchedule specifies a duty cycle (to the second granularity), based on a traditional crontab specification. It is computed initially and stored as bit sets.

func (*SpecSchedule) Next

func (s *SpecSchedule) Next(t time.Time) time.Time

Next returns the next time this schedule is activated, greater than the given time. If no time can be found to satisfy the schedule, return the zero time.

Directories

Path Synopsis
internal
mtx
Package mtx provides thread-safe wrappers for values and maps using read-write mutexes.
Package mtx provides thread-safe wrappers for values and maps using read-write mutexes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL