b2evolution

Multilingual multiuser multiblog engine

b2evolution Technical Documentation (Version 1.9) [ class tree: main ] [ index: main ] [ all elements ]

Source for file cron_exec.php

Documentation is available at cron_exec.php

  1. <?php
  2. /**
  3.  * Execute cron jobs.
  4.  *
  5.  * Example to use CLI:
  6.  * >c:\php4\php cron_exec.php
  7.  * >c:\php4\php-cli cron_exec.php
  8.  */
  9.  
  10.  
  11. /**
  12.  * Include config
  13.  */
  14. require_once dirname(__FILE__).'/../conf/_config.php';
  15.  
  16. /**
  17.  * @todo fp> This MIGHT be overkill. check...
  18.  */
  19. require_once $inc_path .'_main.inc.php';
  20.  
  21. /**
  22.  * Cron support functions
  23.  */
  24. require_once $model_path.'cron/_cron.funcs.php';
  25.  
  26. $quiet 0;
  27. if$is_cli )
  28. // called through Command Line Interface, handle args:
  29.  
  30.     ifisset$_SERVER['argc']$_SERVER['argv') )
  31.     {
  32.         $argc $_SERVER['argc'];
  33.         $argv $_SERVER['argv'];
  34.     }
  35.  
  36.     ifisset($argv) )
  37.     // may not be set for CGI
  38.         foreacharray_slice($argv1as $v )
  39.         {
  40.             switch$v )
  41.             {
  42.                 case '-h':
  43.                 case '--help':
  44.                     // display help:
  45.                     echo $argv[0]." - Execute cron jobs for b2evolution\n";
  46.                     echo "\n";
  47.                     echo "Options:\n";
  48.                     echo " -q --quiet: Be quiet (do not output a message, if there are no jobs).\n";
  49.                     echo "             This is especially useful, when running as a cron job.\n";
  50.                     exit(0);
  51.                     break;
  52.  
  53.                 case '-q':
  54.                 case '--quiet':
  55.                     // increase quietness:
  56.                     $quiet++;
  57.                     break;
  58.  
  59.                 default:
  60.                     echo 'Invalid option "'.$v.'". Use "-h" or "--help" for a list of options.'."\n";
  61.                     exit(1);
  62.             }
  63.         }
  64.     }
  65. }
  66. else
  67. // This is a web request:
  68.     ?>
  69.     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  70.     <html>
  71.     <head>
  72.         <title>Cron exec</title>
  73.         <link rel="stylesheet" type="text/css" href="<?php echo $rsc_url ?>css/basic.css">
  74.     </head>
  75.     <body>
  76.         <h1>Cron exec</h1>
  77.         <p>This script will execute the next task in the cron queue.
  78.         You should normally call it with the CLI (command line interface) version of PHP
  79.         and automate that call through a cron.</p>
  80.     <?php
  81. }
  82.  
  83. /*
  84.  * The following will feel a little bloated...
  85.  * BUT it is actually a pretty nifty design to prevent double execution of tasks without any transaction!
  86.  * The trick is to rely on the primary key of the cron__log table.
  87.  */
  88.  
  89. // Get next task to run in queue which has not started execution yet:
  90. $sql 'SELECT *
  91.                     FROM T_cron__task LEFT JOIN T_cron__log ON ctsk_ID = clog_ctsk_ID
  92.                  WHERE clog_ctsk_ID IS NULL
  93.                      AND ctsk_start_datetime <= '.$DB->quotedate2mysql($localtimenow) ).'
  94.                  ORDER BY ctsk_start_datetime ASC, ctsk_ID ASC
  95.                  LIMIT 1';
  96. $task $DB->get_row$sqlOBJECT0'Get next task to run in queue which has not started execution yet' );
  97.  
  98. ifempty$task ) )
  99. {
  100.     if$quiet )
  101.     {
  102.         cron_log'There is no task to execute yet.' );
  103.     }
  104. }
  105. else
  106. {
  107.     $ctsk_ID $task->ctsk_ID;
  108.     $ctsk_name $task->ctsk_name;
  109.  
  110.     cron_log'Requesting lock on task #'.$ctsk_ID.' ['.$ctsk_name.']' );
  111.  
  112.     $DB->halt_on_error false;
  113.     $DB->show_errors false;
  114.     $sql 'INSERT INTO T_cron__log( clog_ctsk_ID, clog_realstart_datetime, clog_status)
  115.                     VALUES( '.$ctsk_ID.', '.$DB->quotedate2mysql($localtimenow) ).', "started" )';
  116.     // Duplicate query for tests!
  117.     // $DB->query( $sql, 'Request lock' );
  118.     if$DB->query$sql'Request lock' != )
  119.     // This has no affected exactly ONE row: error! (probably locked -- duplicate key -- by a concurrent process)
  120.         $DB->show_errors true;
  121.         $DB->halt_on_error true;
  122.         cron_log'Could not lock. Task is probably handled by another process.' );
  123.     }
  124.     else
  125.     {
  126.         if!empty$task->ctsk_repeat_after ) )
  127.         {    // This task wants to be repeated:
  128.             // Note: we use the current time for 2 reasons: 1) prevent scheduling something in the past AND 2) introduce variety so that everyone doesn't run his repeated tasks at the same exact time, especially pings, pollings...
  129.             if$task->ctsk_controller == 'cron/_antispam_poll.job.php' )
  130.             {    // THIS IS A HACK. Guess why we need that!? :P  Please do not override or you'll kill our server :(
  131.                 $new_start_datetime $localtimenow rand4320086400 )// 12 to 24 hours
  132.             }
  133.             else
  134.             {    // Normal
  135.                 $new_start_datetime $localtimenow $task->ctsk_repeat_after;
  136.             }
  137.             $sql 'INSERT INTO T_cron__task( ctsk_start_datetime, ctsk_repeat_after, ctsk_name, ctsk_controller, ctsk_params )
  138.                             VALUES( '.$DB->quote(date2mysql($new_start_datetime)).', '.$DB->quote($task->ctsk_repeat_after).', '
  139.                                                 .$DB->quote($ctsk_name).', '.$DB->quote($task->ctsk_controller).', '.$DB->quote($task->ctsk_params).' )';
  140.             $DB->query$sql'Schedule repeated task.' );
  141.         }
  142.  
  143.         $DB->show_errors true;
  144.         $DB->halt_on_error true;
  145.         cron_log'Starting task #'.$ctsk_ID.' ['.$ctsk_name.'] at '.date'H:i:s'$localtimenow ).'.' );
  146.  
  147.         ifempty($task->ctsk_params) )
  148.         {
  149.             $cron_params array();
  150.         }
  151.         else
  152.         {
  153.             $cron_params unserialize$task->ctsk_params );
  154.         }
  155.  
  156.         // The job may need to know its ID (to set logical locks for example):
  157.         $cron_params['ctsk_ID'$ctsk_ID;
  158.  
  159.         // EXECUTE
  160.         call_job$task->ctsk_controller$cron_params );
  161.  
  162.         // Record task as finished:
  163.         ifempty($timestop) )
  164.         {
  165.             $timestop time($time_difference;
  166.         }
  167.         $sql ' UPDATE T_cron__log
  168.                                 SET clog_status = '.$DB->quote($result_status).',
  169.                                         clog_realstop_datetime = '.$DB->quotedate2mysql($timestop) ).',
  170.                                         clog_messages = '.$DB->quote($result_message/* May be NULL */.'
  171.                             WHERE clog_ctsk_ID = '.$ctsk_ID;
  172.         $DB->query$sql'Record task as finished.' );
  173.     }
  174. }
  175.  
  176.  
  177. //echo 'detecting timeouts...';
  178. // Detect timed out tasks:
  179. $sql ' UPDATE T_cron__log
  180.                         SET clog_status = "timeout"
  181.                     WHERE clog_status = "started"
  182.                                 AND clog_realstart_datetime < '.$DB->quotedate2mysqltime($time_difference $cron_timeout_delay ) );
  183. $DB->query$sql'Detect cron timeouts.' );
  184.  
  185.  
  186.  
  187. if$is_cli )
  188. // This is a web request:
  189.     echo '<p><a href="cron_exec.php">Refresh Now!</a></p>';
  190.     echo '<p>This page should refresh automatically in 15 seconds...</p>';
  191.     echo '<!-- This is invalid HTML but it is SOOOOOO helpful! (Delay will be triggered when we reach that point -->';
  192.     echo '<meta http-equiv="Refresh" content="15" />';
  193.  
  194.     debug_info();
  195.     ?>
  196.     </body>
  197.     </html>
  198.     <?php
  199. }
  200. ?>

Documentation generated on Tue, 18 Dec 2007 19:06:29 +0100 by phpDocumentor 1.4.0