Deferred: a simple library for doing things later
(require deferred) | package: deferred |
Deferred allows you to run things at a specified time or after a specified elapsed time. It’s sort of like a less complete cron, usable from within racket.
The central notion within deferred is that of the task queue: a central place where tasks go to wait. (This is in fact a misnomer: it’s actually just a set, and tasks handle their own scheduling independently of each other, but I found it helpful to think about it in this way.) There’s a default queue that requires no setup, but if you want a bunch of separate taskqueues, you can achieve this with parameterization.
1 Adding a task to a taskqueue
In deferred, a "task" is just a zero-argument function to be run (which is internally wrapped into its own thread. There are several ways to add a function to a taskqueue, with various levels of convenience.
For running a function at a specified date, use defer:
For running a function after a specified interval, use after:
For convenience, there are shortcuts for running something at a specific hour and minute today or tomorrow:
syntax
(today-at hour minute body ...)
hour : (</c 24)
minute : (</c 60)
syntax
(tomorrow-at hour minute body ...)
hour : (</c 24)
minute : (</c 60)
2 Interacting with task queues
Most of the time, it shouldn’t really be necessary to interact with the task queues directly. Nonetheless, if you want to inspect the contents of a queue, or override the default queueing behavior in defer, there are functions to do so.
Return #t if the enqueue message was sent successfully, #f otherwise.
Return nothing if the dequeue message was sent successfully, #f if the queue is not running. Fails silently if the thread is not in the queue.
procedure
(inspect-queue) → (or/c void? #f)
3 Shutting down a queue
When you’re done with a queue, you can shut it down to remove any pending tasks, and prevent enqueueing any additional ones.
procedure
(wait-queue) → void?
procedure
(purge-queue) → (or/c void? #f)
Returns nothing if the purge message was successfully sent or #f if the queue is not running.
procedure
(shutdown-queue) → (or/c void? #f)
Returns nothing if the shutdown message was successfully sent or #f if the queue is not running.
4 Making your own task queues
If you need multiple separate queues, or your own custom queues, you can accomplish this by parameterizing queue-manager:
parameter
(queue-manager) → thread?
(queue-manager qm) → void? qm : thread?
= (thread queue-manager-loop)
procedure
(queue-manager-loop [queue-items]) → void?
queue-items : (set/c any/c #:kind 'immutable) = (set)
5 Utility functions
procedure
(eta-from-offset [ #:seconds sec #:minutes minutes #:hours hours #:days days]) → date? sec : number? = 0 minutes : number? = 0 hours : number? = 0 days : number? = 0