Go Schedule
A schedule utility to generate all the dates.
go get github.com/io-da/schedule
This library is intended to be used as an utility for generating time.Time structs.
It should provide an alternative to Linux's Cron and Crontab with some extra spice.
This library purposely does not implement the actual job handling/execution.
Clean codebase. No reflection, no closures.
Schedule is the struct used to represent a set of retrievable time.Time structs.
Optionally it can also contain a CronExpression that will only start producing time.Time structs after the scheduled ones.
Schedules can be initialized in 2 ways: schedule.At(at ...time.Time)
or schedule.In(in ...time.Duration)
.
schedule.At
creates a Schedule that returns the provided time.Time structs.
schedule.In
creates a Schedule that returns time.Now()
plus the provided time.Duration values.
schedule.As
creates a Schedule that returns the dates generated by the provided CronExpression.
The time.Time structs can be retrieved by executing the function sch.Following()
.
Moving the Schedule state forward is achieved by executing the function sch.Next()
.
Optionally it is also possible to provide a CronExpression to a Schedule (sch.AddCron(crn *CronExpression)
).
The CronExpression will only start to be used after the schedules times.
CronExpression struct represents a full crontab expression.
An expression is initialized using the function schedule.Cron()
.
This expression is defined by using a set of functions designed for readability.
The CronExpression does not generate times it self. For that we need a CronInstance.
At 00:00 on day-of-month 29 and on Sunday in February. (0 0 29 2 0):
Cron().
OnMonths(time.February).
OnDays(29).
OnWeekdays(time.Sunday)
Iterator expressions are any type that implements the IteratorExpression interface.
These are used to represent sets of values.
type IteratorExpression interface {
Next(from int, inc bool) (int, bool)
Contains(val int) bool
}
The library provides 2 different ones.
BetweenExpression:
type BetweenExpression struct {
x int
y int
step int
}
This expression also allows configuration of it's stepping value using Every(s int)
.
ListExpression:
type ListExpression struct {
values []int
}
(Between) Every 2 hours: Cron().OnHours(BetweenHours(0,22).Every(2))
(List) Specifically at 0 and 12 hours: Cron().OnHours(ListHours(0,12))
To start generating time.Time structs, we just need to create a CronInstance from the CronExpression crn.NewInstance(from time.Time)
.
It is required to provide a from time.Time for the CronInstance to be able to identify its following time.Time.
The CronInstance exposes only 2 functions.
Next() error
Following() time.Time
Next()
is used to determine the next following time.Time. Every execution advances it's internal state.
Following()
is used to retrieve the determined time.Time. It can be retrieved without any consequence.
import (
"github.com/io-da/schedule"
)
func main() {
// instantiate a schedule that produces a time.Time one hour in the future
sch := schedule.In(time.Hour)
// setup a cron to start producing time.Time every hour thereafter
sch.AddCron(schedule.Cron().EveryHour())
for {
// check if the schedule/cron expired
if err := sch.Next(); err == nil {
// and potentially handle the error
hypotheticalLogger.error(err)
break
}
// retrieve the determined time.Time
at := sch.Following()
// and handle it
hypotheticalTaskManager.Add(hypotheticalTask, at)
}
}
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.