cron-style scheduling - run every cycle

Issue #55 resolved
Vovodroid created an issue

When cycle period is less than cron specified interval action is triggered every cycle inside of cron interval.

Example:

set daemon 1 # set poll cycle 1 second

check program some_program with path "/opt/some_program" every "22 * * "


Expected - run once somewhere during minute 22th. Result - run every second during minute 22th.

So if we write every " * * *" we get not once per minute, but every second.

Comments (8)

  1. Tildeslash repo owner
    • changed component to Monit
    • changed version to 5.9

    We agree, given that minute is the lowest resolution and if minute is specified then it should only run the check once. The problem is the poll-cycle and that Monit runs single threaded, which means that when the time is up, Monit might be asleep. The solution we want to use, is to drop the poll-cycle and instead use an even-loop and run checks in parallel. We just need to get our head above the water to start this work. But in the mean time, we should set a flag if minute is specified in the cron-string and mark the check to only run once within the hour +-. This is probably good enough for 99% of use cases. Exactness is not super critical. I mean, if the check runs 09:07 instead of 09:05 due to poll-cycle and time taken by checks it should be fine for most cases, right?

  2. Vovodroid reporter

    ----------------mark the check to only run once within the hour +-. This is probably good enough for 99% of use cases Not sure that once a hour can serve as once per minute.

    ---------------We just need to get our head above the water to start this work Why just not to remember last run time and on each cycle to decide whether it should be run now according to cron-string?

  3. Vovodroid reporter

    --------mark the check to only run once within the hour

    Well, I created little workaround patch: just don't run more often than once per 60 sec., so it works also for "* * * * *".

    monit.h line 600:

    typedef struct myevery {
            ..........................
            time_t last_run;
    } Every_T;
    

    y.tab.c line 4856:

                       current->every.type = EVERY_CRON;
                       current->every.last_run = 0;
    

    validate.c check_skip(Service_T s, time_t Time) { (change parameter time name):

    } else if (s->every.type == EVERY_CRON && (! Time_incron(s->every.spec.cron, Time) || time(0)-s->every.last_run < 60)) {
    
    ...............
            s->monitor &= ~MONITOR_WAITING;
            s->every.last_run = time(0);
            return FALSE;
    
  4. Tildeslash repo owner

    Fixes #55 Only run cron style checks once per minute. Minute is the lowest resolution in the cron string, but if poll-cycle time is lower than one minute the check could run several times in a minute. Plans to drift back in time to pick up missing checks is postponed, because checks runs single threaded with poll-cycle time resolution it is nearly impossible to do this exact.

    → <<cset e56b1c67658c>>

  5. Log in to comment