4.5 Timers

In addition to process, inetd-style, and systemd-style services discussed before, another type of service is available: timers.

Timers, you guessed it, execute a command or call a procedure periodically. They work like other services: they can be started, stopped, unloaded, and so on. The constructor and destructor shown below let you define a timer; they are exported by (shepherd service timer), so make sure to add a line like this to your configuration file if you’d like to use them:

(use-modules (shepherd service timer))

Timers fire on calendar events: “every Sunday at noon”, “everyday at 11AM and 8PM”, “on the first of each month”, etc. If you ever used cron, mcron, or systemd timers, this is similar. Calendar events are specified using the calendar-event procedure, which defines constraints on each calendar component: months, days of week, hours, minutes, and so on. Here are a few examples:

;; Every Sunday and every Wednesday, at noon.
(calendar-event #:hours '(12) #:minutes '(0)
                #:days-of-week '(sunday wednesday))

;; Everyday at 11AM and 8PM.
(calendar-event #:hours '(11 20) #:minutes '(0))

;; At 9:10AM on the first and fifteenth of each month.
(calendar-event #:days-of-month '(1 15)
                #:hours '(9) #:minutes '(10))
Procedure: calendar-event [#:months any-month] [#:days-of-month any-day] [#:days-of-week any-day-of-week] [#:hours any-hour] [#:minutes any-minute] [#:seconds ’(0)]

Return a calendar event that obeys the given constraints. Raise an error if one of the values is out of range.

All the arguments are lists of integers as commonly used in the Gregorian calendar, except for days-of-week which is a list of symbols denoting weekdays: 'monday, 'tuesday, etc.

Users familiar with the venerable Vixie cron can instead convert cron-style date specifications to a calendar event data structure using the cron-string->calendar-event procedure described below.

Procedure: cron-string->calendar-event str

Convert str, which contains a Vixie cron date line, into the corresponding calendar-event. Raise an error if str is invalid.

A valid cron date line consists of 5 space-separated fields: minute, hour, day of month, month, and day of week. Each field can be an integer, or a comma-separate list of integers, or a range. Ranges are represented by two integers separated by a hyphen, optionally followed by slash and a number of repetitions. Here are examples:

30 4 1,15 * *

4:30AM on the 1st and 15th of each month;

5 0 * * *

five minutes after midnight, every day;

23 0-23/2 * * 1-5

23 minutes after the hour every two hour, on weekdays.

To create a timer, you create a service with the procedures described below as its start and stop methods (see Defining Services).

Procedure: make-timer-constructor event action [#:occurrences +inf.0] [#:log-file #f] [#:max-duration #f] [#:wait-for-termination? #f]

Return a procedure for use as the start method of a service. The procedure will perform action for occurrences iterations of event, a calendar event as returned by calendar-event. action may be either a command (returned by command) or a thunk; in the latter case, the thunk must be suspendable or it could block the whole shepherd process.

When log-file is true, log the output of action to that file rather than in the global shepherd log.

When wait-for-termination? is true, wait until action has finished before considering executing it again; otherwise, perform action strictly on every occurrence of event, at the risk of having multiple instances running concurrently.

When max-duration is true, it is the maximum duration in seconds that a run may last, provided action is a command. Past max-duration seconds, the timer’s process is forcefully terminated with signal termination-signal.

Procedure: make-timer-destructor

Return a procedure for the stop method of a service whose constructor was given by make-timer-destructor.

As we have seen above, make-timer-destructor can be passed a command to execute. Those are specified using the command procedure below.

Procedure: command line [#:user #f] [#:group #f] [#:supplementary-groups ’()] [#:environment-variables (default-environment-variables)] [#:directory (default-service-directory)] [#:resource-limits ’()]

Return a new command for line, a program name and argument list, to be executed as user and group, with the given environment-variables, in directory, and with the given resource-limits.

These arguments are the same as for fork+exec-command and related procedures (see fork+exec-command).

It’s also possible to add a trigger action to timer services, such that one can trigger it with:

herd trigger service

To do that, you would add the predefined timer-trigger-action to the service’s actions field (see Defining Services).

Variable: timer-trigger-action

This is the trigger service action. When invoked, its effect is to invoke the action passed to make-timer-constructor.

See timer example, to see how to put it all together.

Last, this module also provides timer-service, a sort of “meta” timer service that lets you dynamically create timed services from the command line. See Timer Service.