b2evolution

Multilingual multiuser multiblog engine

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

Documentation generated on Sat, 06 Mar 2010 03:51:02 +0100 by phpDocumentor 1.4.2. This site is hosted and maintained by Daniel HAHLER (Contact).