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