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