cron has had a long reign as the arbiter of scheduled system tasks on
Unix systems. However, it has some critical flaws that make its use
somewhat fraught. Delivering cronjobs is Hard. Inserting fragments
into crontab in a reliable and predictable fashion is tricky. The
fragment-based delivery provided by /etc/cron.d helps, but it’s not perfect.
It’s also far too easy to create systemic problems on a large scale. If
your cron fragment is packaged and deployed to multiple systems, the
result is that every system runs that job at exactly the same time. For
jobs that hit a single server, like checking for package updates, the
result is that every machine connects to the server at the same time,
often overloading it. Like job delivery, it’s possible to work around
the problem, but it takes some gymnastics to do so.
cron also lacks validation, error handling, dependency management, and a
host of other features.
Enter the Periodic Restarter and Scheduled Services.
The Periodic Restarter is a delegated restarter, at
svc:/system/svc/periodic-restarter:default, that allows the creation of
SMF services that represent scheduled or periodic tasks. Scheduled
Services have all the benefits that other SMF services have, including
error handling, consistent logging, dependencies, predictable lifecycle
management, and more. We’ve baked in a some extra goodies on top of
that, which I’ll explain in a bit.
As you can imagine, scheduled services have a slightly different model
than other services. The most visible difference is that instances of
scheduled services can be in the “online” state even when the task isn’t
running. For these services, the “online” state means that the service
has all of its dependencies met, is scheduled, and is ready to execute
when the appropriate time comes. The service will stay in the “online”
state while the job is executing, as well. Other than that, though,
scheduled services behave like any other SMF service.
So what other features do scheduled services have that make them
superior to ordinary cronjobs?
The first is that scheduled services have a mechanism to execute jobs
that have been missed due to system downtime. Simply by setting a flag
in the service configuration, the periodic restarter will execute your
task when the system comes back up, once all of its dependencies have
been met. If your task was set to run at 1:35 in the morning, but it
was rebooted over that time, your task will still execute.
The other nice feature is that scheduled services have built in
randomness. The task has an execution interval that can be constrained
as necessary, but only as necessary. Everything else is automatically
randomized. Maybe a task has to be run once a month, but it doesn’t
matter at all when during the month. For such a task, the only thing
that must be specified is that the task should execute once a month.
From there, the periodic restarter will pick a time during the month to
execute the job. Another task, such as log rotation, may need to run
during off hours every day. In that case, you can constrain the
schedule so that it runs during a particular hour, but the exact time
during that hour will be randomized. This feature enables the
deployment of scheduled tasks on a wide scale without having to consider
load balancing, both between systems and between tasks on the same system.
In subsuquent updates, we’ll discuss how to create scheduled services as
well as how to inspect some of the extra state that comes along with