MediaWiki  REL1_20
rebuildLocalisationCache.php
Go to the documentation of this file.
00001 <?php
00002 
00032 require_once( __DIR__ . '/Maintenance.php' );
00033 
00039 class RebuildLocalisationCache extends Maintenance {
00040         public function __construct() {
00041                 parent::__construct();
00042                 $this->mDescription = "Rebuild the localisation cache";
00043                 $this->addOption( 'force', 'Rebuild all files, even ones not out of date' );
00044                 $this->addOption( 'threads', 'Fork more than one thread', false, true );
00045                 $this->addOption( 'outdir', 'Override the output directory (normally $wgCacheDirectory)',
00046                         false, true );
00047         }
00048 
00049         public function memoryLimit() {
00050                 if ( $this->hasOption( 'memory-limit' ) ) {
00051                         return parent::memoryLimit();
00052                 }
00053                 return '1000M';
00054         }
00055 
00056         public function execute() {
00057                 global $wgLocalisationCacheConf;
00058 
00059                 $force = $this->hasOption( 'force' );
00060                 $threads = $this->getOption( 'threads', 1 );
00061                 if ( $threads < 1 || $threads != intval( $threads ) ) {
00062                         $this->output( "Invalid thread count specified; running single-threaded.\n" );
00063                         $threads = 1;
00064                 }
00065                 if ( $threads > 1 && wfIsWindows() ) {
00066                         $this->output( "Threaded rebuild is not supported on Windows; running single-threaded.\n" );
00067                         $threads = 1;
00068                 }
00069                 if ( $threads > 1 && !function_exists( 'pcntl_fork' ) ) {
00070                         $this->output( "PHP pcntl extension is not present; running single-threaded.\n" );
00071                         $threads = 1;
00072                 }
00073 
00074                 $conf = $wgLocalisationCacheConf;
00075                 $conf['manualRecache'] = false; // Allow fallbacks to create CDB files
00076                 if ( $force ) {
00077                         $conf['forceRecache'] = true;
00078                 }
00079                 if ( $this->hasOption( 'outdir' ) ) {
00080                         $conf['storeDirectory'] = $this->getOption( 'outdir' );
00081                 }
00082                 $lc = new LocalisationCache_BulkLoad( $conf );
00083 
00084                 $codes = array_keys( Language::fetchLanguageNames( null, 'mwfile' ) );
00085                 sort( $codes );
00086 
00087                 // Initialise and split into chunks
00088                 $numRebuilt = 0;
00089                 $total = count( $codes );
00090                 $chunks = array_chunk( $codes, ceil( count( $codes ) / $threads ) );
00091                 $pids = array();
00092                 foreach ( $chunks as $codes ) {
00093                         // Do not fork for only one thread
00094                         $pid = ( $threads > 1 ) ? pcntl_fork() : -1;
00095 
00096                         if ( $pid === 0 ) {
00097                                 // Child, reseed because there is no bug in PHP:
00098                                 // http://bugs.php.net/bug.php?id=42465
00099                                 mt_srand( getmypid() );
00100                                 $numRebuilt = $this->doRebuild( $codes, $lc, $force );
00101                                 // Abuse the exit value for the count of rebuild languages
00102                                 exit( $numRebuilt );
00103                         } elseif ( $pid === -1 ) {
00104                                 // Fork failed or one thread, do it serialized
00105                                 $numRebuilt += $this->doRebuild( $codes, $lc, $force );
00106                         } else {
00107                                 // Main thread
00108                                 $pids[] = $pid;
00109                         }
00110                 }
00111                 // Wait for all children
00112                 foreach ( $pids as $pid ) {
00113                         $status = 0;
00114                         pcntl_waitpid( $pid, $status );
00115                         // Fetch the count from the return value
00116                         $numRebuilt += pcntl_wexitstatus( $status );
00117                 }
00118 
00119                 $this->output( "$numRebuilt languages rebuilt out of $total\n" );
00120                 if ( $numRebuilt === 0 ) {
00121                         $this->output( "Use --force to rebuild the caches which are still fresh.\n" );
00122                 }
00123         }
00124 
00133         private function doRebuild( $codes, $lc, $force ) {
00134                 $numRebuilt = 0;
00135                 foreach ( $codes as $code ) {
00136                         if ( $force || $lc->isExpired( $code ) ) {
00137                                 $this->output( "Rebuilding $code...\n" );
00138                                 $lc->recache( $code );
00139                                 $numRebuilt++;
00140                         }
00141                 }
00142                 return $numRebuilt;
00143         }
00144 
00150         public function setForce( $forced = true ) {
00151                 $this->mOptions['force'] = $forced;
00152         }
00153 }
00154 
00155 $maintClass = "RebuildLocalisationCache";
00156 require_once( RUN_MAINTENANCE_IF_MAIN );