Search code examples
mysqllinuxjob-schedulingubuntu-server

Linux: schedule command at a specific, different predetermined time every day


I have to run a command every day at a different time. The times are known in advance and saved in a MySQL database in the familiar YYYY-MM-DD HH:MM:SS format.

What I thought of:

  1. cron schedule the job for the exact time the first day, then make the script itself modify the crontab entry with the correct time for the next day.

  2. cron scheduling the job at approximately the right time, then make it read the exact time from the database and sleep until then.

  3. cron schedule the job execution every minute, and leave it to the script to determine whether the current date/time corresponds to the right execution time; proceded if it is, exit if not.

  4. at submit the job the first day with at, then make it read the next day's time from the database and resubmit itself for then with at.

Additional info:

The command is a PHP script that composes the message of the day and sends it to all users registered to the website. I can consider other technologies if they solve this problem better. I would like to retain the ability of rebooting the server (outside of the intended execution hour) without worrying too much about jobs getting lost, therefore solutions 1. and 3. look better under this aspect. I'm starting with two commands to be run at two different times of the day, but I could soon end up with dozens more of similar jobs to be scheduled at different times every day, so I would prefer to avoid clutter as much as possible. I'd probably go with option 3 at this point.

The question(s): Is there a better / preferred / established way of accomplishing this task? Solutions other that those mentioned above are welcome. What are the main drawbacks (of your recommended solution) I should be aware of?


Solution

  • I ended up using solution 3. above and am quite satisfied with it so far.

    All the logic is in the .php file, which is responsible to:

    1. save the current date/time in a variable (e.g. $now)
    2. perform any considerations on it
    3. scan the database in search of a matching date/time

    This actually allows for a reasonable degree of flexibility:

    1. I can choose not to run any commands if a certain semaphore file exists:

      if (file_exists($filename)) {exit;}
      
    2. I can set parameters in an option file enabling e.g. debug or test modes:

      include parameters.php
      if ($debug === true) {error_reporting(E_ALL);}
      
    3. I can avoid bothering users if it is, let's say, new year's day:

      if (date('m-d') == '01-01') {exit;}
      
    4. I can introduce delays based on custom logic:

      if (date('w', strtotime($now)) === '0') {$now = date('Y-m-d H:i:s', strtotime($now . ' +15 minutes'));}