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