crontab: cron-like scheduling
(require crontab) | package: crontab-lib |
This package provides functionality for scheduling work inside of Racket using cron-like syntax.
1 Reference
1.1 Crontabs
syntax
(crontab [schedule-expr handler-expr] ...+)
schedule-expr : string?
handler-expr : (-> exact-integer? any)
Handlers are executed synchronously within each thread, meaning procedures that take a long time to execute may cause runs to be skipped.
> (define stop (crontab ["* * * * * *" println])) 1743512080
> (sleep 5)
1743512081
1743512082
1743512083
1743512084
1743512085
> (stop)
1.2 Schedules
Schedules constrain the components of a timestamp to match specific moments in time.
Schedules can be used as synchronizable events. A schedule is ready for synchronization when the value of (current-seconds) is less than or equal to the value of (schedule-next s) as of the moment the event is synchronized on. The synchronization result of a schedule is the schedule itself and the timestamp (in seconds) it became ready for synchronization at.
> (require racket/date)
> (define (~date ts) (parameterize ([date-display-format 'iso-8601]) (date->string (seconds->date ts) #t))) >
> (define now (find-seconds 30 21 10 19 8 2022)) > > (~date now) "2022-08-19T10:21:30"
> (~date (schedule-next (parse-schedule "* * * * * *") now)) "2022-08-19T10:21:30"
> (~date (schedule-next (parse-schedule "* * * * *") now)) "2022-08-19T10:22:00"
> (~date (schedule-next (parse-schedule "0 5-23/5 * * *") now)) "2022-08-19T15:00:00"
> (~date (schedule-next (parse-schedule "0 12 * * 5") now)) "2022-08-19T12:00:00"
> (~date (schedule-next (parse-schedule "* * 29 2 *") now)) "2024-02-29T00:00:00"
>
> (let ([s (parse-schedule "0 * * * *")]) (for/fold ([ts now]) ([_ (in-range 10)]) (define new-ts (schedule-next s ts)) (displayln (~date new-ts)) (add1 new-ts)))
2022-08-19T11:00:00
2022-08-19T12:00:00
2022-08-19T13:00:00
2022-08-19T14:00:00
2022-08-19T15:00:00
2022-08-19T16:00:00
2022-08-19T17:00:00
2022-08-19T18:00:00
2022-08-19T19:00:00
2022-08-19T20:00:00
1660939201
> > (sync (parse-schedule "* * * * * *"))
#<schedule>
1743512085
procedure
(parse-schedule s [local-time?]) → schedule?
s : string? local-time? : boolean? = #t
“@” commands are not supported,
“0” is not a valid weekday, and
month and weekday names are not supported.
When a schedule contains 6 fields instead of 5, the first field is treated as a constraint on the seconds component of a timestamp.
Timestamps are processed by the schedule according to the local time zone if local-time? is #t and UTC otherwise.
procedure
(schedule-matches? s timestamp) → boolean?
s : schedule? timestamp : exact-integer?
procedure
(schedule-next s [start-timestamp]) → exact-integer?
s : schedule? start-timestamp : exact-integer? = (current-seconds)
procedure
(schedule->string s) → string?
s : schedule?