MediaWiki
REL1_21
|
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 finalSetup() { 00057 # This script needs to be run to build the inital l10n cache. But if 00058 # $wgLanguageCode is not 'en', it won't be able to run because there is 00059 # no l10n cache. Break the cycle by forcing $wgLanguageCode = 'en'. 00060 global $wgLanguageCode; 00061 $wgLanguageCode = 'en'; 00062 return parent::finalSetup(); 00063 } 00064 00065 public function execute() { 00066 global $wgLocalisationCacheConf; 00067 00068 $force = $this->hasOption( 'force' ); 00069 $threads = $this->getOption( 'threads', 1 ); 00070 if ( $threads < 1 || $threads != intval( $threads ) ) { 00071 $this->output( "Invalid thread count specified; running single-threaded.\n" ); 00072 $threads = 1; 00073 } 00074 if ( $threads > 1 && wfIsWindows() ) { 00075 $this->output( "Threaded rebuild is not supported on Windows; running single-threaded.\n" ); 00076 $threads = 1; 00077 } 00078 if ( $threads > 1 && !function_exists( 'pcntl_fork' ) ) { 00079 $this->output( "PHP pcntl extension is not present; running single-threaded.\n" ); 00080 $threads = 1; 00081 } 00082 00083 $conf = $wgLocalisationCacheConf; 00084 $conf['manualRecache'] = false; // Allow fallbacks to create CDB files 00085 if ( $force ) { 00086 $conf['forceRecache'] = true; 00087 } 00088 if ( $this->hasOption( 'outdir' ) ) { 00089 $conf['storeDirectory'] = $this->getOption( 'outdir' ); 00090 } 00091 $lc = new LocalisationCache_BulkLoad( $conf ); 00092 00093 $codes = array_keys( Language::fetchLanguageNames( null, 'mwfile' ) ); 00094 sort( $codes ); 00095 00096 // Initialise and split into chunks 00097 $numRebuilt = 0; 00098 $total = count( $codes ); 00099 $chunks = array_chunk( $codes, ceil( count( $codes ) / $threads ) ); 00100 $pids = array(); 00101 foreach ( $chunks as $codes ) { 00102 // Do not fork for only one thread 00103 $pid = ( $threads > 1 ) ? pcntl_fork() : -1; 00104 00105 if ( $pid === 0 ) { 00106 // Child, reseed because there is no bug in PHP: 00107 // http://bugs.php.net/bug.php?id=42465 00108 mt_srand( getmypid() ); 00109 $numRebuilt = $this->doRebuild( $codes, $lc, $force ); 00110 // Abuse the exit value for the count of rebuild languages 00111 exit( $numRebuilt ); 00112 } elseif ( $pid === -1 ) { 00113 // Fork failed or one thread, do it serialized 00114 $numRebuilt += $this->doRebuild( $codes, $lc, $force ); 00115 } else { 00116 // Main thread 00117 $pids[] = $pid; 00118 } 00119 } 00120 // Wait for all children 00121 foreach ( $pids as $pid ) { 00122 $status = 0; 00123 pcntl_waitpid( $pid, $status ); 00124 // Fetch the count from the return value 00125 $numRebuilt += pcntl_wexitstatus( $status ); 00126 } 00127 00128 $this->output( "$numRebuilt languages rebuilt out of $total\n" ); 00129 if ( $numRebuilt === 0 ) { 00130 $this->output( "Use --force to rebuild the caches which are still fresh.\n" ); 00131 } 00132 } 00133 00142 private function doRebuild( $codes, $lc, $force ) { 00143 $numRebuilt = 0; 00144 foreach ( $codes as $code ) { 00145 if ( $force || $lc->isExpired( $code ) ) { 00146 $this->output( "Rebuilding $code...\n" ); 00147 $lc->recache( $code ); 00148 $numRebuilt++; 00149 } 00150 } 00151 return $numRebuilt; 00152 } 00153 00159 public function setForce( $forced = true ) { 00160 $this->mOptions['force'] = $forced; 00161 } 00162 } 00163 00164 $maintClass = "RebuildLocalisationCache"; 00165 require_once( RUN_MAINTENANCE_IF_MAIN );