Skip to content

cl-schedule is a scheduling library in Common Lisp.

Notifications You must be signed in to change notification settings

jcguu95/cl-schedule

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cl-schedule (v2): a scheduling library in CL

1. Installation & Usage

Although the older version (v1) is available on Quicklisp, the current version (v2) may not yet be listed. To use this program, download it to your local-projects directory and evaluate the form in Lisp:

(ql:quickload :cl-schedule)
(in-package :cl-schedule)

To run the test cases, evaluate the form

(ql:quickload :cl-schedule.test)

2. Examples

To run a function on every minute

(defun hello () (format t "Hello!") (terpri))

(schedule! :func #'hello
           :time '(:second 0))

A more complicated time-spec that replicates */25 5-6,10 4 7 1-3 (cron-style) is

(defun 25-multi (n) (= 0 (mod n 25)))

(schedule! :func #'hello
           :time '(:second 0
                   :minute (satisfies 25-multi)
                   :hour   (or (integer 5 6)
                               (member 10))
                   :date   4
                   :month  7
                   ;; day (0 1 2 3 4 5 6) means (Mon Tue Wed Thu Fri Sat Sun)
                   ;; so instead of 1-3, we use 0-2.
                   :day    (integer 0 2)))

The keywords satisfies, or, integer, and member are integral components of Common Lisp’s type system domain-specific language. Our time-spec language extends this functionality to support a broader range of use cases.

If a time-spec becomes too complex, you can use the #'dry-run function to obtain a list of all universal times that satisfy the specified time range. This utility can be invaluable when debugging or testing the behavior of your program. For instance, consider the following example:

(assert
 (equal- (mapcar #'local-time:universal-to-timestamp
                 (dry-run '(:second 0 ; time-spec
                            :minute 0
                            :hour   (8 20))
                          :init '(2020 1 1 12 59 59)
                          :range (* 3 86400) ; search for 3 days
                          ))
         '(@2020-01-01T20:00:00.000000+08:00
           @2020-01-02T08:00:00.000000+08:00
           @2020-01-02T20:00:00.000000+08:00
           @2020-01-03T08:00:00.000000+08:00
           @2020-01-03T20:00:00.000000+08:00
           @2020-01-04T08:00:00.000000+08:00)))

We support very general time-specs (e.g. any function). For details, please refer to doc/time-spec.org. More examples for #'schedule! can be found in doc/examples.org.

3. How it works under the hood

The system includes two background threads: the scheduler and the dispatcher. The scheduler periodically wakes up and schedules each task in the *schedules* list to the *actions* hash table. This hash table uses universal time as keys and stores lists of schedules as values. Meanwhile, the dispatcher wakes up every second to check the current universal time and invoke the function associated with each enabled schedule stored in the corresponding list.

By default, any conditions are automatically passed and relevant information is printed to *standard-output*. However, the behavior of the system can be modified by adjusting the definition of the #'wrap-with-simple-condition-handler function.

4. FAQ

  • Q: How can I contribute?
  • A: To make a contribution, please refer to the documentation at doc/todo.org.
  • Q: What happens if a schedule is missed, such as when the operating system is in sleep mode during a scheduled task?
  • A: The cl-schedule library does not have built-in support for re-running missed schedules or checking the schedule’s status. However, it should be possible to achieve this functionality by implementing functions that remember relevant information.
  • Q: Is it possible to view the schedule’s history?
  • A: We are currently working on adding this feature. Soon, users will be able to view a list of past schedule calls made by cl-schedule.
  • Q: What is the relationship between v1 and v2?
  • A: Version 2 of cl-schedule is a complete rewrite of version 1. Unlike v1, which relied on igorpikman/clon, v2 is independent of any external dependencies. Additionally, v2 uses more functions than macros, making it more transparent and easier to inspect. V2 also provides a flexible sub-language for specifying times (time-spec), which enables users to programmatically define schedules with greater precision.

About

cl-schedule is a scheduling library in Common Lisp.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Common Lisp 100.0%