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