How quickly is CRON triggered?
Asked Answered
D

4

7

First Example

Suppose I have a CRON job

 30 2 * * * ....

Then this would run every time when it is 2:30 at night (local time).

Now suppose I have the time zone Europe/Germany and it's 2017-10-29 (the day when DST is switched). Then this CRON job would run twice, right?

Second Example

Suppose I have the time zone Europe/Germany and the CRON job

 30 11 * * * ....

As Germany never had a DST change at 11:30, this will not interfere. But the user could change the local time. To be super clear: This question is NOT about DST.

For the following test cases, I would like to know if/how often the CRON job gets scheduled:

  1. At 11:29:58.0, the user sets the time to 11:31:00
  2. At 11:29:59.1, the user sets the time to 11:31:00
  3. At 11:29:59.6, the user sets the time to 11:31:00
  4. At 11:30:01.0, the user sets the time to 11:29:59.7 - is CRON executed directly afterwards?

They boil down to How quickly is CRON triggered?, where the 4th one also has the question if CRON stores that it was already executed for that minute.

Another variant of the same question:

  1. At 11:29:59, the NTP service corrects the time to 11:31:00 - will the job be executed that day at all?
Durrett answered 16/9, 2018 at 12:45 Comment(1)
I think your fifth point is the most interesting one.Circumfluent
A
8

The easiest way to answer this with confidence is to take a look at the source for the cron daemon. There are a few versions online like this, or you can use apt-get source cron.

The tick cycle in cron is to repeatedly sleep for a minute, or less if there is a job coming up. Immediately after emerging from the sleep, it checks the time and treats the result as one of these wakeupKind values:

  • Expected time - run any jobs we were expecting
  • Small jump forwards (up to 5 minutes) - run the jobs for the intervening minutes
  • Medium jump forwards (up to 3 hours, so this would include DST starting in spring) - run any wildcard jobs first (because the catch up could take more than a minute), then catch up on the intervening fixed time jobs
  • Large jump (3 hours or more either way) - start over with the current time
  • Jump backwards (up to 3 hours, so including the end of DST) - because any fixed time jobs have 'probably' already run, only run any wildcard jobs until the time is caught up again

If in doubt, the source comments these wakeupKind values clearly.


Edit

To follow up on whether sleep() could be affected by a clock change, it looks like the answer is indirectly there in a couple of the Linux man pages.

  • Firstly the notes for the sleep() function confirm that is implemented by nanosleep()
  • The notes for nanosleep() say Linux measures the time using the CLOCK_MONOTONIC clock (even though POSIX.1 says it shouldn't)
  • Scroll down a bit in the docs for clock_settime() to see the explanation of CLOCK_MONOTONIC, which explains it is not affected by jumps in the system time, but it would be affected by incremental NTP style clock sync adjustments.

So in summary, a system admin style clock change will have no effect on the sleep(). But for example if an NTP adjustment came in and said to 'gently' advance the clock, cron would experience a series of slightly short sleep() function calls.

Assault answered 22/9, 2018 at 14:29 Comment(3)
Thank you! I think this is pretty much what I was looking for. Somebody mentioned that sleep(x) is not dependent on the system time. Do you have a resource at hand which explains how sleep works / which system resources it needs?Durrett
Time to talk about CLOCK_MONOTONIC in the Linux kernel. See the update on the answer.Assault
Here is your well-deserved bounty. Thank you :-)Durrett
C
1

There are many implementations of cron systems (See here). One of the most commonly used cron's is Vixie cron. And its man page states:

Daylight Saving Time and other time changes

Local time changes of less than three hours, such as those caused by the Daylight Saving Time changes, are handled in a special way. This only applies to jobs that run at a specific time and jobs that run with a granularity greater than one hour. Jobs that run more frequently are scheduled normally.

If time was adjusted one hour forward, those jobs that would have run in the interval that has been skipped will be run immediately. Conversely, if time was adjusted backwards, running the same job twice is avoided.

Time changes of more than 3 hours are considered to be corrections to the clock or the timezone, and the new time is used immediately.

source: man 8 cron

I believe this answers most of your points.

In addition to point five:

  1. At 11:29:59, the NTP service corrects the time to 11:31:00 - will the job be executed that day at all?

First of, if NTP corrects the time with more then a minute, you have a very bad clock! This should not happen too often. Generally, you might have such a step when you enable NTP but then it should be much less.

In any case, if the DeltaT is not to high, generally below 125 ms, your system will slew the time. Slewing the time means to change the virtual frequency of the software clock to make the clock go faster or slower until the requested correction is achieved. Slewing the clock for a larger amount of time may require some time, too. For example standard Linux adjusts the time with a rate of 0.5ms per second.

This implies, (under the assumption of Vixie cron, and probably many others):

  • If NTP jumps more then 3 hours, the job is skipped
  • If NTP jumps less then 3 hours but more then 125 ms, Vixie cron handles the job nicely by assuming the concepts of the time-jumps.
  • If NTP corrects the time for less then 125 ms, cron does not notice the time-jump due to the slewing.

Interesting information:

Circumfluent answered 28/9, 2018 at 9:58 Comment(1)
"it should not happen" is not an answer to "what happens if ...".Durrett
H
0

You're actually asking two related questions. The general answer is it depends[1], but I'll answer based on the Debian Linux installation I'm on right now:

How does cron handle DST changes and other 'special' time-related events?

On my Debian Linux system cron handles 'DST and other time-related changes/fixes' (per the man page) so that jobs don't get run twice or skipped due to changes like DST. (See https://debian-handbook.info/browse/stable/sect.task-scheduling-cron-atd.html for more specifics) Related to the 5th point raised in your second question, I would expect these same facilities to deal with NTP-related time jumps but don't know for certain.

How often is cron triggered and how quickly does it pick up my crontab changes?

Again, on my Debian Linux system the cron daemon wakes up once a minute and will detect and utilize any crontab changes man since the previous check/run one minute ago. Note that there is no guarantee that cron fires off at 12:00:00 or 12:00:59 or any specific time between (only that it fire when the time is 12:00:??) so in the event that you change a crontab at 12:00:17 but cron fired at 12:00:13, your changes will not be picked up until the next run (most likely at 12:01:13 though there might be a slight amount of variance due to the Linux scheduler)

[1] It Depends...

The precise answer absolutely depends both on the platform (Linux/Unix/BSD/OS X/Windows) and the particular implementation of cron (there have been several over the decades with derivatives of Vixie cron being prevalent on Linux and BSD per https://en.wikipedia.org/wiki/Vixie_cron). If you're running something other than Linux, the man page / documentation for your implementation should provide details as to the specifics of how often it runs, picks up modified crontabs, DST handling etc. If you really need to know the specific details, df778899 is right in that you should look at the source code for your implementation as needed... because sometimes software/documentation is buggy.

Hebel answered 26/9, 2018 at 6:59 Comment(4)
"Again, on my Debian Linux system the cron daemon wakes up once a minute" - which minute? UTC minute or system minute? When I change the system time ever 30ms, I doubt CRON would wake up?Durrett
Minute as determined by sleeping until 60 seconds have elapsed since last firing (i.e. based on a call to something along the lines of sleep(), not an absolute time) and then adjusting for any discontinuities (i.e. DST or NTP related changes) when woken up again. Not sure where the 30ms is coming from: in most environments you'll have ping times in the 10's to 100's of ms so trying to adjust the time that frequently would be fruitless as a big part of what NTP has to do is measure network latency and jitter over longer time frames.Hebel
The 30ms is just an number I came up with to enforce an answer to my question. I could write a malware script that changes the time randomly and frequently. This question is not about the normal case, but about possible bad cases. With this imaginary malware script one hase to know about the nasty details. What does it even mean to sleep 60 seconds if the system time is randomly changed every 30ms?Durrett
This would not impact when cron next fires as calls like sleep() are based on timers (i.e. timing circuitry that runs independent of system time) as opposed to time (i.e. the Real Time Clock in your computer.) So I would expect that cron would fire again as expected after a minute has passed (and would continue to do so every 60 seconds) but the question of how would it handle a pathological case of malware messing with the system time like that I couldn't answer. But let's be honest, that's yet another and different question.Hebel
P
-2

On mac OS:

$> man cron
...
Available options:

 -s      Enable special handling of situations when the GMT offset of the local timezone changes, such as the switches between the standard time and daylight saving time.

         The jobs run during the GMT offset changes time as intuitively expected.  If a job falls into a time interval that disappears (for example, during the switch from standard time) to daylight saving time
         or is duplicated (for example, during the reverse switch), then it is handled in one of two ways:

         The first case is for the jobs that run every at hour of a time interval overlapping with the disappearing or duplicated interval.  In other words, if the job had run within one hour before the GMT
         offset change (and cron was not restarted nor the crontab(5) changed after that) or would run after the change at the next hour.  They work as always, skip the skipped time or run in the added time as
         usual.

         The second case is for the jobs that run less frequently.  They are executed exactly once, they are not skipped nor executed twice (unless cron is restarted or the user's crontab(5) is changed during
         such a time interval).  If an interval disappears due to the GMT offset change, such jobs are executed at the same absolute point of time as they would be in the old time zone.  For example, if exactly
         one hour disappears, this point would be during the next hour at the first minute that is specified for them in crontab(5).

 -o      Disable the special handling of situations when the GMT offset of the local timezone changes, to be compatible with the old (default) behavior.  If both options -o and -s are specified, the option
         specified last wins.
Prescind answered 17/9, 2018 at 15:21 Comment(9)
After reading this, I still don't know the answer to my question.Durrett
Not sure how I can be more precise on this. If your job is not during a time change -> normal behavior For every hour job: You got a job at xx:30, change is from 2am to 3am, your 2:30am job is skip. Same job change is from 2h59 to 2am, your 2:30am job is run twice Job that have larger interval (like day job) such jobs are executed at the same absolute point of time as they would be in the old time zone So you got a job at 2:30am everyday, time goes 2->3am, job will run at 3:30am Same job, time goes 2h59 -> 2h, job was run at 2:30am. For #2, default cron is run every minute.Prescind
It's quite expected behavior to be honest. If there is 25h in your day and run the job every hour then it will be run 25 time. If there is 23h then it will run 23 time. If you job execute everyday, then it will execute once a day.Prescind
Here is my mental model I have of CRON: It is just another process handled by the operating system. Meaning it gets execution time assigned whenever the OS decides. Although unlikely, there is no guarantee that the job gets executed within any given timeframe. Realistically, I would expect the CRON job to get execution time at least once a minute. But maybe not every 500ms. In that time NTP could update the system time. That update could be more than a minute. If CRON has no possibility to find out that an update happend, it will just not execute its job.Durrett
My question is NOT about DST, but about other changes of the local time. I think I made this pretty clear with "As Germany never had a DST change at 11:30, this will not interfere. But the user could change the local time."Durrett
Man read the doc! It's quite clear. If it's time changes related to GMT offset you can handle it with -s if not it will be the default behavior. In your case its default behavior. Cron is trigger every minutes, therefore if when you clock changes minutes, it execute all the job that match the time query you defined in your file. Imagine you run the cron manually every minute and you will have the behavior. On top of it, all your describing is OS specific on how the clock & the scheduler is handled, there is no link to CRON.Prescind
Also, I don't get why you're not simply trying it ? CRON only support minutes, meaning you can easily have a job at 11:30:00 the clock at 11:30:25, rewind it to 11:29:25 and wait a 35 second for the CRON to be executed. I don't see why you're even looking in the ms timeframe.Prescind
I'm not "simply trying it" because it is not that simple. I cannot control the OS scheduler / system time on such a level. I'm not saying this is a problem that occurs often. I'm asking if this is a problem that COULD occur. It's similar to a race condition. Have you ever tried to "simply try" a race condition?Durrett
Of course you can try a race condition. By having the right parameter set up, right testing, you can test it and reproduce it. Thankfully you can, or you will almost never be able to figure out your race condition.Prescind

© 2022 - 2024 — McMap. All rights reserved.