MediaWiki
REL1_24
|
00001 <?php 00031 class RefreshLinksJob2 extends Job { 00032 function __construct( $title, $params ) { 00033 parent::__construct( 'refreshLinks2', $title, $params ); 00034 // Base jobs for large templates can easily be de-duplicated 00035 $this->removeDuplicates = !isset( $params['start'] ) && !isset( $params['end'] ); 00036 } 00037 00042 function run() { 00043 global $wgUpdateRowsPerJob; 00044 00045 $linkCache = LinkCache::singleton(); 00046 $linkCache->clear(); 00047 00048 if ( is_null( $this->title ) ) { 00049 $this->error = "refreshLinks2: Invalid title"; 00050 return false; 00051 } 00052 00053 // Back compat for pre-r94435 jobs 00054 $table = isset( $this->params['table'] ) ? $this->params['table'] : 'templatelinks'; 00055 00056 // Avoid slave lag when fetching templates. 00057 // When the outermost job is run, we know that the caller that enqueued it must have 00058 // committed the relevant changes to the DB by now. At that point, record the master 00059 // position and pass it along as the job recursively breaks into smaller range jobs. 00060 // Hopefully, when leaf jobs are popped, the slaves will have reached that position. 00061 if ( isset( $this->params['masterPos'] ) ) { 00062 $masterPos = $this->params['masterPos']; 00063 } elseif ( wfGetLB()->getServerCount() > 1 ) { 00064 $masterPos = wfGetLB()->getMasterPos(); 00065 } else { 00066 $masterPos = false; 00067 } 00068 00069 $tbc = $this->title->getBacklinkCache(); 00070 00071 $jobs = array(); // jobs to insert 00072 if ( isset( $this->params['start'] ) && isset( $this->params['end'] ) ) { 00073 # This is a partition job to trigger the insertion of leaf jobs... 00074 $jobs = array_merge( $jobs, $this->getSingleTitleJobs( $table, $masterPos ) ); 00075 } else { 00076 # This is a base job to trigger the insertion of partitioned jobs... 00077 if ( $tbc->getNumLinks( $table, $wgUpdateRowsPerJob + 1 ) <= $wgUpdateRowsPerJob ) { 00078 # Just directly insert the single per-title jobs 00079 $jobs = array_merge( $jobs, $this->getSingleTitleJobs( $table, $masterPos ) ); 00080 } else { 00081 # Insert the partition jobs to make per-title jobs 00082 foreach ( $tbc->partition( $table, $wgUpdateRowsPerJob ) as $batch ) { 00083 list( $start, $end ) = $batch; 00084 $jobs[] = new RefreshLinksJob2( $this->title, 00085 array( 00086 'table' => $table, 00087 'start' => $start, 00088 'end' => $end, 00089 'masterPos' => $masterPos, 00090 ) + $this->getRootJobParams() // carry over information for de-duplication 00091 ); 00092 } 00093 } 00094 } 00095 00096 if ( count( $jobs ) ) { 00097 JobQueueGroup::singleton()->push( $jobs ); 00098 } 00099 00100 return true; 00101 } 00102 00108 protected function getSingleTitleJobs( $table, $masterPos ) { 00109 # The "start"/"end" fields are not set for the base jobs 00110 $start = isset( $this->params['start'] ) ? $this->params['start'] : false; 00111 $end = isset( $this->params['end'] ) ? $this->params['end'] : false; 00112 $titles = $this->title->getBacklinkCache()->getLinks( $table, $start, $end ); 00113 # Convert into single page refresh links jobs. 00114 # This handles well when in sapi mode and is useful in any case for job 00115 # de-duplication. If many pages use template A, and that template itself 00116 # uses template B, then an edit to both will create many duplicate jobs. 00117 # Roughly speaking, for each page, one of the "RefreshLinksJob" jobs will 00118 # get run first, and when it does, it will remove the duplicates. Of course, 00119 # one page could have its job popped when the other page's job is still 00120 # buried within the logic of a refreshLinks2 job. 00121 $jobs = array(); 00122 foreach ( $titles as $title ) { 00123 $jobs[] = new RefreshLinksJob( $title, 00124 array( 'masterPos' => $masterPos ) + $this->getRootJobParams() 00125 ); // carry over information for de-duplication 00126 } 00127 return $jobs; 00128 } 00129 00133 public function getDeduplicationInfo() { 00134 $info = parent::getDeduplicationInfo(); 00135 // Don't let highly unique "masterPos" values ruin duplicate detection 00136 if ( is_array( $info['params'] ) ) { 00137 unset( $info['params']['masterPos'] ); 00138 } 00139 return $info; 00140 } 00141 }