taskman/cron

  Source   Edit

This module implements the cron format for the scheduler. Cron formats are defined either with the cron macro or initCron

Example:

import taskman/cron
# * * * * *
# Default value for each field is every val
# The cron macro uses x in place of *
assert initCron() == cron(x, x, x, x, x)

# 4 10 * * *
assert initCron({4.MinuteRange}, {10.HourRange}) == cron(4, 10, x, x, x)

# 4-10 4,5,6 * * sun,mon
assert initCron(
  {4.MinuteRange .. 10},
  {4.HourRange, 5, 6}, 
  weekDays = {dSun, dMon}
) == cron(4 - 10, {4, 5, 6}, weekDays = {dSun, dMon})

# every second minute
assert initCron(everyMinute / 2) == cron(minutes = x / 2)
This implements cron in a slightly non standard way in that both monthDays and weekDays are checked e.g.

Example:

import taskman/cron
let 
  start = dateTime(2000, mJan, 1)
  form  = cron(x, x, 10, x, dSun)
# In normal cron it would match 2000-01-10 (Which is a monday)
assert start.next(form) == dateTime(2000, mSep, 10)

Types

Cron = object
  minutes*: set[MinuteRange]
  hours*: set[HourRange]
  monthDays*: set[MonthdayRange]
  months*: set[Month]
  weekDays*: set[WeekDay]
The five star (*) values of a cronjob   Source   Edit
TooFarAheadCron = object of CatchableError
  
Called in the rare case that a cron job cannot find a next available date   Source   Edit

Consts

everyHour = {0..23}
Use with cron task to run every hour   Source   Edit
everyMinute = {0..59}
Use with cron task to run every minute   Source   Edit
everyMonth = {mJan..mDec}
Use with cron task to run every month   Source   Edit
everyMonthDay = {1..31}
use with cron task to run every day in the month   Source   Edit
everyWeekDay = {dMon..dSun}
Use with cron task to run every day in the week   Source   Edit
maxYears = 3
  Source   Edit

Procs

func `/`[T: CronRanges](values: set[T]; n: int): set[T] {....raises: [].}
Returns every nth value starting from the first value in values

Example:

# Set of values to run every second day
assert everyWeekDay / 2 == {dMon, dWed, dFri, dSun} 
# Only use every third hour in our range
assert {5.HourRange .. 15} / 4 == {5.HourRange, 9, 13}
# It only does every second value
assert {dMon, dWed, dSun} / 2 == {dMon, dSun}
  Source   Edit
func initCron(minutes = everyMinute; hours = everyHour;
              monthDays = everyMonthDay; months = everyMonth;
              weekDays = everyWeekDay): Cron {....raises: [], tags: [].}
Makes a new cron format. Sets passed in cannot be empty (Since that wouldn't make sense)

Example:

let everySecondMinute = initCron(minutes = everyMinute / 2)
let weekendMornings = initCron(hours = {8.HourRange}, weekDays = {dSat, dSun})
  Source   Edit
func isValid(format: Cron): bool {....raises: [], tags: [].}
Checks that a format is valid (Just checks it has no empty sets).

Example:

assert not Cron(minutes: {}).isValid
  Source   Edit
proc next(now: DateTime; format: Cron): DateTime {....raises: [TooFarAheadCron],
    tags: [].}
Returns next date that a cron would run from now   Source   Edit

Macros

macro cron(minutes, hours, monthDays, months, weekDays: untyped = x): Cron
Macro to simplify creating cron formats. Syntax is similar to cron
  • /: Define count
  • {}: Provide list of values
  • -: Define range
  • x: Specify any value

Example:

assert cron(x, x, x, x, x) == initCron() # * * * * *
assert cron(minutes = 5) == initCron(minutes = {5.MinuteRange}) # 5 * * * *

# Do between minutes of 5 and 10 during either 1 am or 5 am
# do this every second day of the month
assert cron(5 - 10, {1, 5}, x / 2, x, x) == initCron(
  {5.MinuteRange .. 10},
  {1.HourRange, 5}, 
  everyMonthDay / 2
)
  Source   Edit