Index: trunk/phase3/includes/RefreshLinksJob.php |
— | — | @@ -47,3 +47,87 @@ |
48 | 48 | return true; |
49 | 49 | } |
50 | 50 | } |
| 51 | + |
| 52 | +/** |
| 53 | + * Background job to update links for a given title. |
| 54 | + * Newer version for high use templates. |
| 55 | + * |
| 56 | + * @ingroup JobQueue |
| 57 | + */ |
| 58 | +class RefreshLinksJob2 extends Job { |
| 59 | + |
| 60 | + function __construct( $title, $params, $id = 0 ) { |
| 61 | + parent::__construct( 'refreshLinks2', $title, $params, $id ); |
| 62 | + } |
| 63 | + |
| 64 | + /** |
| 65 | + * Run a refreshLinks2 job |
| 66 | + * @return boolean success |
| 67 | + */ |
| 68 | + function run() { |
| 69 | + global $wgParser; |
| 70 | + |
| 71 | + wfProfileIn( __METHOD__ ); |
| 72 | + |
| 73 | + $linkCache = LinkCache::singleton(); |
| 74 | + $linkCache->clear(); |
| 75 | + |
| 76 | + if( is_null( $this->title ) ) { |
| 77 | + $this->error = "refreshLinks2: Invalid title"; |
| 78 | + wfProfileOut( __METHOD__ ); |
| 79 | + return false; |
| 80 | + } |
| 81 | + if( !isset($this->params['start']) || !isset($this->params['end']) ) { |
| 82 | + $this->error = "refreshLinks2: Invalid params"; |
| 83 | + wfProfileOut( __METHOD__ ); |
| 84 | + return false; |
| 85 | + } |
| 86 | + $start = intval($this->params['start']); |
| 87 | + $end = intval($this->params['end']); |
| 88 | + |
| 89 | + $dbr = wfGetDB( DB_SLAVE ); |
| 90 | + $res = $dbr->select( array( 'templatelinks', 'page' ), |
| 91 | + array( 'page_namespace', 'page_title' ), |
| 92 | + array( |
| 93 | + 'page_id=tl_from', |
| 94 | + "tl_from >= '$start'", |
| 95 | + "tl_from <= '$end'", |
| 96 | + 'tl_namespace' => $this->title->getNamespace(), |
| 97 | + 'tl_title' => $this->title->getDBkey() |
| 98 | + ), __METHOD__ |
| 99 | + ); |
| 100 | + |
| 101 | + # Not suitable for page load triggered job running! |
| 102 | + # Gracefully switch to refreshLinks jobs if this happens. |
| 103 | + if( php_sapi_name() != 'cli' ) { |
| 104 | + $jobs = array(); |
| 105 | + while( $row = $dbr->fetchObject( $res ) ) { |
| 106 | + $title = Title::makeTitle( $row->page_namespace, $row->page_title ); |
| 107 | + $jobs[] = new RefreshLinksJob( $title, '' ); |
| 108 | + } |
| 109 | + Job::batchInsert( $jobs ); |
| 110 | + return true; |
| 111 | + } |
| 112 | + # Re-parse each page that transcludes this page and update their tracking links... |
| 113 | + while( $row = $dbr->fetchObject( $res ) ) { |
| 114 | + $title = Title::makeTitle( $row->page_namespace, $row->page_title ); |
| 115 | + $revision = Revision::newFromTitle( $title ); |
| 116 | + if ( !$revision ) { |
| 117 | + $this->error = 'refreshLinks: Article not found "' . $title->getPrefixedDBkey() . '"'; |
| 118 | + wfProfileOut( __METHOD__ ); |
| 119 | + return false; |
| 120 | + } |
| 121 | + wfProfileIn( __METHOD__.'-parse' ); |
| 122 | + $options = new ParserOptions; |
| 123 | + $parserOutput = $wgParser->parse( $revision->getText(), $title, $options, true, true, $revision->getId() ); |
| 124 | + wfProfileOut( __METHOD__.'-parse' ); |
| 125 | + wfProfileIn( __METHOD__.'-update' ); |
| 126 | + $update = new LinksUpdate( $title, $parserOutput, false ); |
| 127 | + $update->doUpdate(); |
| 128 | + wfProfileOut( __METHOD__.'-update' ); |
| 129 | + wfProfileOut( __METHOD__ ); |
| 130 | + } |
| 131 | + |
| 132 | + return true; |
| 133 | + } |
| 134 | +} |
Index: trunk/phase3/includes/LinksUpdate.php |
— | — | @@ -193,34 +193,46 @@ |
194 | 194 | } |
195 | 195 | |
196 | 196 | function queueRecursiveJobs() { |
| 197 | + global $wgUpdateRowsPerJob; |
197 | 198 | wfProfileIn( __METHOD__ ); |
198 | 199 | |
199 | | - $batchSize = 100; |
200 | 200 | $dbr = wfGetDB( DB_SLAVE ); |
201 | | - $res = $dbr->select( array( 'templatelinks', 'page' ), |
202 | | - array( 'page_namespace', 'page_title' ), |
203 | | - array( |
204 | | - 'page_id=tl_from', |
| 201 | + $res = $dbr->select( 'templatelinks', |
| 202 | + array( 'tl_from' ), |
| 203 | + array( |
205 | 204 | 'tl_namespace' => $this->mTitle->getNamespace(), |
206 | 205 | 'tl_title' => $this->mTitle->getDBkey() |
207 | 206 | ), __METHOD__ |
208 | 207 | ); |
209 | 208 | |
210 | | - $done = false; |
211 | | - while ( !$done ) { |
212 | | - $jobs = array(); |
213 | | - for ( $i = 0; $i < $batchSize; $i++ ) { |
214 | | - $row = $dbr->fetchObject( $res ); |
215 | | - if ( !$row ) { |
216 | | - $done = true; |
| 209 | + $numRows = $res->numRows(); |
| 210 | + $numBatches = ceil( $numRows / $wgUpdateRowsPerJob ); |
| 211 | + $realBatchSize = $numRows / $numBatches; |
| 212 | + $start = false; |
| 213 | + $jobs = array(); |
| 214 | + do { |
| 215 | + for( $i = 0; $i <= $realBatchSize - 1; $i++ ) { |
| 216 | + $row = $res->fetchRow(); |
| 217 | + if( $row ) { |
| 218 | + $id = $row[0]; |
| 219 | + } else { |
| 220 | + $id = false; |
217 | 221 | break; |
218 | 222 | } |
219 | | - $title = Title::makeTitle( $row->page_namespace, $row->page_title ); |
220 | | - $jobs[] = new RefreshLinksJob( $title, '' ); |
221 | 223 | } |
222 | | - Job::batchInsert( $jobs ); |
223 | | - } |
| 224 | + $params = array( |
| 225 | + 'start' => $start, |
| 226 | + 'end' => ( $id !== false ? $id - 1 : false ), |
| 227 | + ); |
| 228 | + $jobs[] = new RefreshLinksJob2( $this->mTitle, $params ); |
| 229 | + |
| 230 | + $start = $id; |
| 231 | + } while ( $start ); |
| 232 | + |
224 | 233 | $dbr->freeResult( $res ); |
| 234 | + |
| 235 | + Job::batchInsert( $jobs ); |
| 236 | + |
225 | 237 | wfProfileOut( __METHOD__ ); |
226 | 238 | } |
227 | 239 | |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -146,6 +146,7 @@ |
147 | 147 | 'RdfMetaData' => 'includes/Metadata.php', |
148 | 148 | 'RecentChange' => 'includes/RecentChange.php', |
149 | 149 | 'RefreshLinksJob' => 'includes/RefreshLinksJob.php', |
| 150 | + 'RefreshLinksJob2' => 'includes/RefreshLinksJob.php', |
150 | 151 | 'RegexlikeReplacer' => 'includes/StringUtils.php', |
151 | 152 | 'ReplacementArray' => 'includes/StringUtils.php', |
152 | 153 | 'Replacer' => 'includes/StringUtils.php', |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -1621,6 +1621,7 @@ |
1622 | 1622 | */ |
1623 | 1623 | $wgJobClasses = array( |
1624 | 1624 | 'refreshLinks' => 'RefreshLinksJob', |
| 1625 | + 'refreshLinks2' => 'RefreshLinksJob2', |
1625 | 1626 | 'htmlCacheUpdate' => 'HTMLCacheUpdateJob', |
1626 | 1627 | 'html_cache_update' => 'HTMLCacheUpdateJob', // backwards-compatible |
1627 | 1628 | 'sendMail' => 'EmaillingJob', |