Cron Design: Cron Script Part 2

MPG UniCenter

MPG UniCenter

Uniform Server Portable Cron Design

At the heart of Uniform Server’s portable Cron is a configuration file. This is periodically read into an array the period is defined by Cron time, which has a default setting of one minute. The array is scanned line-by-line comparing any time settings to the current time on finding a match the corresponding script is run.

This page looks at the foreach loop in detail.

Block Parameters

Before performing any foreach-loop logic processing, option values need to be extracted from the configuration file.

Every time the script is run the configuration file is read into an array. First task of the foreach-loop is to extract a block’s option values. Each time around the loop selects a new block and extracts its option values.

Read Configuration file:

  • Cron’s configuration file cron.ini is read into array $ini_array
  • PHP function's parse_ini_file has second parameter set to true
  • This preserves the file structure when saved to array.

Function Used:


$ini_array = parse_ini_file($file, true);

Extract Option Value:

  • Having the structure preserved means the array can be scanned with 
    a foreach loop that targets only the block title.
  • Hence array $key holds a block title.
foreach($ini_array as $key => $value){ 
} 
  • This $key is used to target options in the bock as follows:
$tim = strtotime("now");        //current time
$tim_s  = strtotime($ini_array[$key]['start']);
$period = $ini_array[$key]['period'];
$path   = $ini_array[$key]['path'];
$ref    = $ini_array[$key]['ref'];

Note: All times are converted to Unix timestamps.

  • $tim Is the current time, all times are compared to this.
  • $tim_s Initial start time extracted from a block option.

Configuration file example:


[dtdns]
start  = 2009-09-21 2:56:52
eriod = 600                 ; 10 Mins as required by DtDNS
;path   = ..\..\plugins\dtdns_updater\dtdns_updater.php
ref = 

[db_backup]
start  = 2009-09-21 2:56:52
period = hourly
path   = ..\..\plugins\db_backup\db_backup.php
ref = 

[moodle]
start  = 2009-09-21 2:56:52
period = hourly
path   = http://localhost/moodle/admin/cron.php
ref = 

[drupal]
start  = 2009-09-21 2:56:52
period = hourly
path   = http://localhost/drupal/cron.php
ref = 
  

Top

Froreach logic

Description:

The foreach logic consists of three if statements.

The first thing to note all time comparisons are relative meaning they use only the greater than or less than comparison. This caters for situations where a user moves the servers from one machine to another. Using an equal’s comparison would potential miss a time slot?

Strictly speaking a start time is not necessary however it does allow staggering of intensive processes by specify a different start time for each process to be run.

  • First if: Is it a new start time or a continuation of a previously triggered time.
    • If the start time is greater than current time a user must have set a new start time. Since this has not been reached there is nothing to do hence force the foreach loop to continue.
    • If the start time is less than current time either a new start time has been reached or it’s a continuation of a previously triggered start time. Hence further processing required.


  • Second if: Is this a continuation of a previously triggered start time or a new start time?
    • If ref is blank a user has requested a new start time. Immediately create a new start reference time by summing the current time and period, save this to the configuration file. Run the required script.
    • If ref is not blank it’s a potential trigger event hence further processing required.


  • Third if:Is this a new trigger event?
    • If the ref time is greater than current time a trigger event has not been reached. Hence nothing to do force the foreach loop to continue.
    • If the ref time is less than current time a trigger event has occurred. Create a new start reference time by summing current time and period, save this to the configuration file. Run the required script.

 

Top

Froreach logic - Alternative flow diagram

Description:

This flow diagram and the above are functionally identical. The above is easier to understand however if directly translated into code leads to the use of a function which is strictly not required.

I prefer the flow diagram on the right although slightly more difficult to read is directly translatable into code and does not require the use of a function.

Code Snippet:

$ini_array = parse_ini_file($file, true); // Read cron.ini into array
foreach($ini_array as $key => $value){    // Scan array's main keys

 $tim = strtotime("now");                        //current time
 $tim_s  = strtotime($ini_array[$key]['start']); // Start time
 $period = $ini_array[$key]['period'];           // Period
 $path   = $ini_array[$key]['path'];             // Path to run script
 $ref    = $ini_array[$key]['ref'];              // Repeat time marker

if((float)$tim > (float)$tim_s){     // New start or started
  if( $ref != ""){                   // It was started
    if( (float)$tim < (float)$ref ){ // Is it a triggered update 
      continue;                      // No: Start next foreach
    }
  }
  //== Eiter a new start or triggered update hence run script

 $ref = $tim + $period;               // Create new repeat time marker
 my_ini_set($file,$key,'ref',$ref);   // Save to ini file for later use 

 // Code to Run File here
}//if
}// End foreach

Flow Diagram  

Top

Summary

That completes all main design areas for portable Cron.

Main point’s script uses relative comparisons so as not to miss a time event. All time references use a Unix timestamp.

Final script is shown on the next page.

Top