r87106 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r87105‎ | r87106 | r87107 >
Date:00:28, 29 April 2011
Author:reedy
Status:deferred
Tags:
Comment:
Modified paths:
  • /branches/iwtransclusion/phase3v2 (modified) (history)
  • /branches/iwtransclusion/phase3v2/includes/Revision.php (modified) (history)
  • /branches/iwtransclusion/phase3v2/includes/Title.php (modified) (history)
  • /branches/iwtransclusion/phase3v2/includes/interwiki/Interwiki.php (modified) (history)

Diff [purge]

Index: branches/iwtransclusion/phase3v2/includes/interwiki/Interwiki.php
@@ -168,6 +168,7 @@
169169 $mc = array(
170170 'iw_url' => $iw->mURL,
171171 'iw_api' => $iw->mAPI,
 172+ iw_wikiid' => $iw->mWikiID,
172173 'iw_local' => $iw->mLocal,
173174 'iw_trans' => $iw->mTrans
174175 );
@@ -271,7 +272,6 @@
272273 return !$msg->exists() ? '' : $msg;
273274 }
274275
275 -
276276
277277 /**
278278 * Transclude an interwiki link.
@@ -291,42 +291,46 @@
292292
293293 } else if( $transAPI !== '' ) {
294294
295 - $fullTitle = $title->getNsText().':'.$title->getText();
296 -
297 - $url1 = $transAPI."?action=query&prop=revisions&titles=$fullTitle&rvprop=content&format=json";
298 -
299 - if ( strlen( $url1 ) > 255 ) {
300 - return false;
301 - }
 295+ $fullTitle = $title->getSemiPrefixedText( );
302296
303 - $finalText = self::fetchTemplateHTTPMaybeFromCache( $url1 );
 297+ $finalText = self::fetchTemplateFromAPI( $wikiID, $transAPI, $fullTitle );
304298
305 - $url2 = $transAPI."?action=parse&text={{".$fullTitle."}}&prop=templates&format=json";
 299+ //Retrieve the list of subtemplates
 300+ $url2 = wfAppendQuery( $transAPI,
 301+ array( 'action' => 'query',
 302+ 'titles' => $fullTitle,
 303+ 'prop' => 'templates',
 304+ 'format' => 'json'
 305+ )
 306+ );
306307
307308 $get = Http::get( $url2 );
308309 $myArray = FormatJson::decode($get, true);
309310
310 - if ( ! empty( $myArray['parse'] )) {
311 - $templates = $myArray['parse']['templates'];
 311+ if ( ! empty( $myArray['query'] )) {
 312+ if ( ! empty( $myArray['query']['pages'] )) {
 313+ $templates = array_pop( $myArray['query']['pages'] );
 314+ if ( ! empty( $templates['templates'] )) {
 315+ $templates = $templates['templates'];
 316+ } else {
 317+ $templates = array( );
 318+ }
 319+ }
312320 }
313321
314 - // TODO: The templates are retrieved one by one. We should get them all in 1 request
 322+ // TODO: The subtemplates are retrieved one by one. We should get them all in 1 request
315323 // Here, we preload and cache the subtemplates
316 - for ($i = 0 ; $i < count( $templates ) ; $i++) {
317 - $newTitle = $templates[$i]['*'];
318 -
319 - $url = $transAPI."?action=query&prop=revisions&titles=$newTitle&rvprop=content&format=json";
320 -
321 - // $newText is unused, but requesting it will put the template in the cache
322 - $newText = self::fetchTemplateHTTPMaybeFromCache( $url );
323 -
324 - }
 324+ self::cacheTemplatesFromAPI( $wikiID, $transAPI, $templates );
 325+
325326 return $finalText;
326327
327328 }
328329 return false;
329330 }
330331
 332+ /**
 333+ * Retrieve the wikitext of a distant page accessing the foreign DB
 334+ */
331335 public static function fetchTemplateFromDB ( $wikiID, $title ) {
332336
333337 $revision = Revision::loadFromTitleForeignWiki( $wikiID, $title );
@@ -339,43 +343,91 @@
340344 return false;
341345 }
342346
343 - public static function fetchTemplateHTTPMaybeFromCache( $url ) {
344 - global $wgTranscludeCacheExpiry;
345 - $dbr = wfGetDB( DB_SLAVE );
346 - $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry );
347 - $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ),
348 - array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) );
349 -
350 - if ( $obj ) {
351 - return $obj->tc_contents;
 347+ /**
 348+ * Retrieve the wikitext of a distant page using the API of the foreign wiki
 349+ */
 350+ public static function fetchTemplateFromAPI( $wikiID, $transAPI, $fullTitle ) {
 351+ global $wgMemc, $wgTranscludeCacheExpiry;
 352+
 353+ $key = wfMemcKey( 'iwtransclustiontext', 'textid', $wikiID, $fullTitle );
 354+ $text = $wgMemc->get( $key );
 355+ if( is_array ( $text ) &&
 356+ isset ( $text['missing'] ) &&
 357+ $text['missing'] === true ) {
 358+ return false;
 359+ } else if ( $text ) {
 360+ return $text;
352361 }
353 -
 362+
 363+ $url = wfAppendQuery(
 364+ $transAPI,
 365+ array( 'action' => 'query',
 366+ 'titles' => $fullTitle,
 367+ 'prop' => 'revisions',
 368+ 'rvprop' => 'content',
 369+ 'format' => 'json'
 370+ )
 371+ );
 372+
354373 $get = Http::get( $url );
355 -
356374 $content = FormatJson::decode( $get, true );
357375
358 - if ( ! empty($content['query']['pages']) ) {
359 -
 376+ if ( isset ( $content['query'] ) &&
 377+ isset ( $content['query']['pages'] ) ) {
360378 $page = array_pop( $content['query']['pages'] );
361 - $text = $page['revisions'][0]['*'];
362 -
363 - } else {
364 -
365 - return wfMsg( 'scarytranscludefailed', $url );
366 -
 379+ if ( $page && isset( $page['revisions'][0]['*'] ) ) {
 380+ $text = $page['revisions'][0]['*'];
 381+ $wgMemc->set( $key, $text, $wgTranscludeCacheExpiry );
 382+ return $text;
 383+ } else {
 384+ $wgMemc->set( $key, array ( 'missing' => true ), $wgTranscludeCacheExpiry );
 385+ }
367386 }
368 -
369 - $dbw = wfGetDB( DB_MASTER );
370 - $dbw->replace( 'transcache', array('tc_url'), array(
371 - 'tc_url' => $url,
372 - 'tc_time' => $dbw->timestamp( ),
373 - 'tc_contents' => $text)
374 - );
375 -
376 - return $text;
 387+ return false;
377388 }
378389
379 -
380 -
381 -
 390+ public static function cacheTemplatesFromAPI( $wikiID, $transAPI, $titles ){
 391+ global $wgMemc, $wgTranscludeCacheExpiry;
 392+
 393+ $outdatedTitles = array( );
 394+
 395+ foreach( $titles as $title ){
 396+ if ( isset ( $title['title'] ) ) {
 397+ $key = wfMemcKey( 'iwtransclustiontext', 'textid', $wikiID, $title['title'] );
 398+ $text = $wgMemc->get( $key );
 399+ if( !$text ){
 400+ $outdatedTitles[] = $title['title'];
 401+ }
 402+ }
 403+ }
 404+
 405+ $batches = array_chunk( $outdatedTitles, 50 );
 406+
 407+ foreach( $batches as $batch ){
 408+ $url = wfAppendQuery(
 409+ $transAPI,
 410+ array( 'action' => 'query',
 411+ 'titles' => implode( '|', $batch ),
 412+ 'prop' => 'revisions',
 413+ 'rvprop' => 'content',
 414+ 'format' => 'json'
 415+ )
 416+ );
 417+ $get = Http::get( $url );
 418+ $content = FormatJson::decode( $get, true );
 419+
 420+ if ( isset ( $content['query'] ) &&
 421+ isset ( $content['query']['pages'] ) ) {
 422+ foreach( $content['query']['pages'] as $page ) {
 423+ $key = wfMemcKey( 'iwtransclustiontext', 'textid', $wikiID, $page['title'] );
 424+ if ( isset ( $page['revisions'][0]['*'] ) ) {
 425+ $text = $page['revisions'][0]['*'];
 426+ } else {
 427+ $text = array ( 'missing' => true );
 428+ }
 429+ $wgMemc->set( $key, $text, $wgTranscludeCacheExpiry );
 430+ }
 431+ }
 432+ }
 433+ }
382434 }
Property changes on: branches/iwtransclusion/phase3v2/includes/interwiki/Interwiki.php
___________________________________________________________________
Modified: svn:mergeinfo
383435 Merged /branches/iwtransclusion/phase3/includes/interwiki/Interwiki.php:r69745-69746,69781,69783
Index: branches/iwtransclusion/phase3v2/includes/Revision.php
@@ -907,7 +907,11 @@
908908 // Caching may be beneficial for massive use of external storage
909909 global $wgRevisionCacheExpiry, $wgMemc;
910910 $textId = $this->getTextId();
911 - $key = wfMemcKey( 'revisiontext', 'textid', $textId );
 911+ if( isset( $this->mWikiID ) ) {
 912+ $key = wfForeignMemcKey( $this->mWikiID, null, 'revisiontext', 'textid', $textId );
 913+ } else {
 914+ $key = wfMemcKey( 'revisiontext', 'textid', $textId );
 915+ }
912916 if( $wgRevisionCacheExpiry ) {
913917 $text = $wgMemc->get( $key );
914918 if( is_string( $text ) ) {
Property changes on: branches/iwtransclusion/phase3v2/includes/Revision.php
___________________________________________________________________
Modified: svn:mergeinfo
915919 Merged /branches/iwtransclusion/phase3/includes/Revision.php:r69745-69746,69781,69783
Index: branches/iwtransclusion/phase3v2/includes/Title.php
@@ -727,6 +727,20 @@
728728 }
729729
730730 /**
 731+ * Return the prefixed title with spaces _without_ the interwiki prefix
 732+ *
 733+ * @return \type{\string} the title, prefixed by the namespace but not by the interwiki prefix, with spaces
 734+ */
 735+ public function getSemiPrefixedText() {
 736+ if ( !isset( $this->mSemiPrefixedText ) ){
 737+ $s = ( $this->mNamespace === NS_MAIN ? '' : $this->getNsText() . ':' ) . $this->mTextform;
 738+ $s = str_replace( '_', ' ', $s );
 739+ $this->mSemiPrefixedText = $s;
 740+ }
 741+ return $this->mSemiPrefixedText;
 742+ }
 743+
 744+ /**
731745 * Get the prefixed title with spaces, plus any fragment
732746 * (part beginning with '#')
733747 *
Property changes on: branches/iwtransclusion/phase3v2/includes/Title.php
___________________________________________________________________
Modified: svn:mergeinfo
734748 Merged /branches/iwtransclusion/phase3/includes/Title.php:r69745-69746,69781,69783
Property changes on: branches/iwtransclusion/phase3v2
___________________________________________________________________
Modified: svn:mergeinfo
735749 Merged /branches/iwtransclusion/phase3:r69745-69746,69781,69783

Follow-up revisions

RevisionCommit summaryAuthorDate
r92987Merge r87106 which is a Merge r69745, r69746, r69781, r69783reedy17:25, 24 July 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r69745Trying to solve a possible issue in caching foreign revision (described in r6...peter1719:42, 22 July 2010
r69746Batch caching for API-retrieved templates, as requested in r69730peter1719:43, 22 July 2010
r69781Negative caching of API-retrieved templates (as requested in r69746) + prefix...peter1709:11, 23 July 2010
r69783Correct style and solve a bug that appears when caching is enabledpeter1710:24, 23 July 2010

Status & tagging log