MediaWiki
REL1_20
|
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 );