Once again, OpenBSD with the simple, obvious solution, that everyone else kinda overlooked. I hope every other cron out there copies and ships this as soon as possible.
Systemd Timers have had this for a while.
Personally I find the OpenBSD solution far more elegant and UNIXy than the systemd one, but to each their own.
What would you say is wrong with RandomizedDelaySec?
RandomizedDelaySec=Even if their cron does...
https://github.com/freebsd/freebsd-src/commit/f5896baf9c429c...
For example, instead of "0-59/10" in the minutes field, "0~59/10" can be used to run a command every 10 minutes where the first command starts at a random offset in the range [0,9]. The high and low numbers are optional, "~/10" can be used instead.But the above point is still true: many jobs take a few minutes to run. 60s of dispersion in start time is better than nothing, but you really want more.
(In this case, things are still quantized to a minute boundary, so you'd really want both).
It was such a breath of fresh air compared to Linux at the time because it was a coherent, engineered, documented system. When you didn't always have reliable internet (and at least for me, even when I did have it was something like 128K DSL), it was a huge deal to have well written man pages, where as on the linux half the time time the man page woud just tell you to scream into the void, err, run gnu info.
This was still in the period when the GPL scared off corps.
It kind of feels like this is putting the policy of "don't all go at once" into the cron mechanism, which is just starting jobs at desired times.
sleep $((RANDOM%=60))
...or longer, at the top of the script your cron is running.
Firstly, OpenBSD is a niche OS, meaning the absolute magnitude of OpenBSD cron jobs out "in the wild" is relatively low.
Second, my understanding is that this is a client-side feature. I.e. if I run a service, this feature only benefits me if a significant portion of my users opt into it.
Third, I have an unsubstantiated suspicion that cron usage relative to systemd usage is also on the decline.
I have to say, these flags are a really nice enhancement to cron.
https://man.freebsd.org/cgi/man.cgi?query=crontab&apropos=0&...
https://man.netbsd.org/NetBSD-9.3-STABLE/crontab.5
http://fcron.free.fr/doc/en/fcrontab.5.html#FCRONTAB.5.ERROR...
Just because it doesn’t consider external executions, it doesn’t mean it’s a bad solution. Horses for courses etc
No, it's gross. By providing that facility in the wrong place it discourages implementing it in the right place to people who come at the problem from the cron perspective.
Wrap the command in a flock-running script. That script goes in the crontab entry. When you're inevitably debugging your cron-scheduled command - paydirt! The command serializes itself still while you're manually testing instead of shitting itself.
If it's a single command or pipeline... adding the layer of indirection to have a script that runs flock is more opaque. Might as well put it in cron and trust cron to only run it once.
You are confusing running a process with running a task from scheduler.
You are aware that flock(1) is a thing, right? And that a defacto core tenet of UNIX is composability of disparate programs that do one thing well?
EDIT: In addition, the Task Scheduler in Windows has this type of option, so it may help those sys admins coming from that environment, leveraging their existing knowledge
In crons that do not support something like this, you can introduce a random delay with a Perl oneliner. For example,
# Start within the first 10 minutes of a matching hour.
0 */8 * * * perl -e 'sleep rand 10*60' && ~/.config/jobs/fetch-tcl-logs 0 */8 * * * sleep "$(jot -r 1 0 599)" && ~/.config/jobs/fetch-tcl-logs sleep $((RANDOM % 600)) && fetch-tcl-logs #!/bin/bash
set -e
HEIIONCALL_API_KEY="redacted_api_key_goes_here"
HEIIONCALL_TRIGGER_ID="redacted_trigger_id_goes_here"
AUTHORIZATION_HEADER="Authorization: Bearer ${HEIIONCALL_API_KEY}"
CHECKIN_URL="https://api.heiioncall.com./triggers/${HEIIONCALL_TRIGGER_ID}/checkin"
if [ "$1" != "--now" ]; then
RANDOM_SLEEP=$[ ( $RANDOM % 55 ) + 1 ]
echo "Sleeping ${RANDOM_SLEEP} seconds before checkin..."
sleep ${RANDOM_SLEEP}s
fi
echo "Checking in..."
exec curl \
-X POST \
--retry 5 --retry-connrefused --retry-max-time 15 --retry-delay 1 \
-H "${AUTHORIZATION_HEADER}" \
"${CHECKIN_URL}"
This script ~/bin/heiioncall-checkin.sh gets called by crond every minute at exactly :00 seconds, so my expected maximum timeout between check-ins is approximately 120 seconds. And I can skip the sleep with "--now" flag for testing. But I'd much rather have this random offset behavior be something optionally built-in to cron, I suppose.[1]: https://www.freedesktop.org/software/systemd/man/systemd.tim...
E.g. Tor network capacity varies over the month due to bandwidth management tending to happen at the begining/end of months
I put together a small busybox-like collection of sysadmin tools, and one of the subcommands is "splay" to sleep for a random amount of time. It's one of those things that is useful surprisingly often, even outside cron.
Btw congrats to the openbsd people for catching up.
Also, just as a sidenote I'm not willing to seriously discuss: I seriously doubt I'd personally ever use random ranges in production. I understand what problem it's supposed to solve, but generally I just really don't want anything random in my systems. If it conflicts with some other cronjobs or whatever, I'd like it to break down deterministically — preferably, all the time, so it's easier to spot, track down and fix it. If it causes any load spikes, I'd like these spikes to be regular, so that I can see that and manually tweak run times so that it'll be more even. If any problems arise, I'd prefer them to arise after somebody changed something, and not just magically one Saturday evening a couple of months later.
The only situation I can think of right away when this is acceptable, is if I have lot of nodes with the same cron config, so it's my attempt to spread out workers of the same type that I know would start at the same time otherwise. But then, why the fuck do I have such a degenerate architecture in the first place?! Maybe I should think about replacing that by something a little more sustainable, like, uh, a centralized scheduler? No, I mean, it's definitely a solution — a quick and easy one, at that — but even then it seems like a solutions to a problem that shouldn't have existed in the first place.