Skip to content

io-da/schedule

Repository files navigation

Go Schedule

A schedule utility to generate all the dates.

Maintainability Test Coverage GoDoc

Installation

go get github.com/io-da/schedule

Overview

  1. Schedule
  2. CronExpression
  3. IteratorExpression
  4. CronInstance
  5. Putting it together

Introduction

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.

Getting Started

Schedule

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

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.

Examples

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)

IteratorExpression

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
}
Examples

(Between) Every 2 hours: Cron().OnHours(BetweenHours(0,22).Every(2))
(List) Specifically at 0 and 12 hours: Cron().OnHours(ListHours(0,12))

CronInstance

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.

Putting it together

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)
    }
}

Contributing

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.

License

MIT