r88821 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r88820‎ | r88821 | r88822 >
Date:19:38, 25 May 2011
Author:aaron
Status:ok
Tags:
Comment:
* Follow-up r88740:
* Moved getRevIncludes() process only to where it's needed for simplicity
* Tweaked getRevIncludes() cache check to try the rev's author's parser options
* Lengthened getRevIncludes() cache time but made it double-check page_latest
* Added cachePendingRevs.php script to rebuild the caches for pending revs
Modified paths:
  • /trunk/extensions/FlaggedRevs/business/RevisionReviewForm.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/dataclasses/FlaggedRevs.class.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/maintenance/cachePendingRevs.php (added) (history)
  • /trunk/extensions/FlaggedRevs/presentation/FlaggedPageView.php (modified) (history)

Diff [purge]

Index: trunk/extensions/FlaggedRevs/maintenance/cachePendingRevs.php
@@ -0,0 +1,59 @@
 2+<?php
 3+/**
 4+ * This script precaches parser output related data of pending revs
 5+ *
 6+ * @ingroup Maintenance
 7+ */
 8+
 9+if ( getenv( 'MW_INSTALL_PATH' ) ) {
 10+ $IP = getenv( 'MW_INSTALL_PATH' );
 11+} else {
 12+ $IP = dirname(__FILE__).'/../../..';
 13+}
 14+
 15+require_once( "$IP/maintenance/Maintenance.php" );
 16+
 17+class CachePendingRevs extends Maintenance {
 18+ public function __construct() {
 19+ parent::__construct();
 20+ $this->mDescription = "Cache pending revision data";
 21+ }
 22+
 23+ public function execute() {
 24+ global $wgUser;
 25+ $dbr = wfGetDB( DB_SLAVE );
 26+ $ret = $dbr->select(
 27+ array( 'flaggedpages', 'revision', 'page' ),
 28+ array_merge( Revision::selectFields(), array( $dbr->tableName( 'page' ) . '.*' ) ),
 29+ array( 'fp_pending_since IS NOT NULL',
 30+ 'page_id = fp_page_id',
 31+ 'rev_page = fp_page_id',
 32+ 'rev_timestamp >= fp_pending_since'
 33+ ),
 34+ __METHOD__
 35+ );
 36+ foreach ( $ret as $row ) {
 37+ $title = Title::newFromRow( $row );
 38+ $article = new Article( $title );
 39+ $rev = new Revision( $row );
 40+ // Trigger cache regeneration
 41+ $start = microtime( true );
 42+ RevisionReviewForm::getRevIncludes( $article, $rev, $wgUser, 'regen' );
 43+ $elapsed = intval( ( microtime( true ) - $start ) * 1000 );
 44+ $this->cachePendingRevsLog(
 45+ $title->getPrefixedDBkey() . " rev:" . $rev->getId() . " {$elapsed}ms" );
 46+ }
 47+ }
 48+
 49+ /**
 50+ * Log the cache message
 51+ * @param $msg String The message to log
 52+ */
 53+ private function cachePendingRevsLog( $msg ) {
 54+ $this->output( wfTimestamp( TS_DB ) . " $msg\n" );
 55+ wfDebugLog( 'cachePendingRevs', $msg );
 56+ }
 57+}
 58+
 59+$maintClass = "CachePendingRevs";
 60+require_once( RUN_MAINTENANCE_IF_MAIN );
Property changes on: trunk/extensions/FlaggedRevs/maintenance/cachePendingRevs.php
___________________________________________________________________
Added: svn:eol-style
161 + native
Index: trunk/extensions/FlaggedRevs/dataclasses/FlaggedRevs.class.php
@@ -714,9 +714,9 @@
715715 # ################ Other utility functions #################
716716
717717 /**
 718+ * Get a memcache storage object
718719 * @param string $val
719720 * @return Object (val,time) tuple
720 - * Get a memcache storage object
721721 */
722722 public static function makeMemcObj( $val ) {
723723 $data = (object) array();
@@ -726,14 +726,17 @@
727727 }
728728
729729 /**
 730+ * Return memc value if not expired
730731 * @param object|false $data makeMemcObj() tuple
731732 * @param Article $article
 733+ * @param $allowStale Use 'allowStale' to skip page_touched check
732734 * @return mixed
733 - * Return memc value if not expired
734735 */
735 - public static function getMemcValue( $data, Article $article ) {
736 - if ( is_object( $data ) && $data->time >= $article->getTouched() ) {
737 - return $data->value;
 736+ public static function getMemcValue( $data, Article $article, $allowStale = '' ) {
 737+ if ( is_object( $data ) ) {
 738+ if ( $allowStale === 'allowStale' || $data->time >= $article->getTouched() ) {
 739+ return $data->value;
 740+ }
738741 }
739742 return false;
740743 }
Index: trunk/extensions/FlaggedRevs/business/RevisionReviewForm.php
@@ -581,30 +581,33 @@
582582 * @param Article $article
583583 * @param Revision $rev
584584 * @param User $user
 585+ * @param string $regen use 'regen' to force regeneration
585586 * @return array( templateIds, fileSHA1Keys )
586587 * templateIds like ParserOutput->mTemplateIds
587588 * fileSHA1Keys like ParserOutput->mImageTimeKeys
588589 */
589 - public static function getRevIncludes( Article $article, Revision $rev, User $user ) {
 590+ public static function getRevIncludes(
 591+ Article $article, Revision $rev, User $user, $regen = ''
 592+ ) {
590593 global $wgParser, $wgMemc;
591 - static $versionCache = array();
592594 wfProfileIn( __METHOD__ );
 595+ $versions = false;
593596 $hash = md5( $article->getTitle()->getPrefixedDBkey() );
594597 # Check process cache first...
595 - $vKey = $rev->getId()."-$hash";
596 - if ( isset( $versionCache[$vKey] ) ) {
597 - wfProfileOut( __METHOD__ );
598 - return $versionCache[$vKey]; // hit
 598+ $key = wfMemcKey( 'flaggedrevs', 'revIncludes', $rev->getId(), $hash );
 599+ if ( $regen !== 'regen' ) {
 600+ $versions = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $article, 'allowStale' );
599601 }
600 - $key = wfMemcKey( 'flaggedrevs', 'revIncludes', $rev->getId(), $hash );
601 - $val = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $article );
602 - if ( is_array( $val ) ) {
603 - $versions = $val; // cache hit
604 - } else {
 602+ if ( !is_array( $versions ) ) { // cache miss
605603 $pOut = false;
606 - if ( $rev->isCurrent() ) { // try current version parser cache
 604+ if ( $rev->isCurrent() ) {
607605 $parserCache = ParserCache::singleton();
 606+ # Try current version parser cache (as anon)...
608607 $pOut = $parserCache->get( $article, $article->makeParserOptions( $user ) );
 608+ if ( $pOut == false && $rev->getUser() ) { // try the user who saved the change
 609+ $author = User::newFromId( $rev->getUser() );
 610+ $pOut = $parserCache->get( $article, $article->makeParserOptions( $author ) );
 611+ }
609612 }
610613 if ( $pOut == false ) {
611614 $title = $article->getTitle();
@@ -620,13 +623,25 @@
621624 $versions = array( $pOut->getTemplateIds(), $pOut->getImageTimeKeys() );
622625 # Save to cache...
623626 $data = FlaggedRevs::makeMemcObj( $versions );
624 - $wgMemc->set( $key, $data, 3600 ); // inclusions may be dynamic
625 - }
626 - # Save to process cache...
627 - if ( count( $versionCache ) > 100 ) {
628 - $versionCache = array(); // sanity
629 - }
630 - $versionCache[$vKey] = $versions;
 627+ $wgMemc->set( $key, $data, 24*3600 ); // inclusions may be dynamic
 628+ } else {
 629+ # Do a link batch query for page_latest...
 630+ $lb = new LinkBatch();
 631+ foreach ( $versions as $ns => $tmps ) {
 632+ foreach ( $tmps as $dbKey => $revIdDraft ) {
 633+ $lb->add( $ns, $dbKey );
 634+ }
 635+ }
 636+ $lb->execute();
 637+ # Update array with the current page_latest values.
 638+ # This kludge is there since $newTemplates (thus $revIdDraft) is cached.
 639+ foreach ( $versions as $ns => $tmps ) {
 640+ foreach ( $tmps as $dbKey => &$revIdDraft ) {
 641+ $title = new Title( $ns, $dbKey );
 642+ $revIdDraft = (int)$title->getLatestRevID();
 643+ }
 644+ }
 645+ }
631646 wfProfileOut( __METHOD__ );
632647 return $versions;
633648 }
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedPageView.php
@@ -7,6 +7,7 @@
88 protected $article = null;
99
1010 protected $diffRevs = null; // assoc array of old and new Revisions for diffs
 11+ protected $oldRevIncludes = null; // ( array of templates, array of file)
1112 protected $isReviewableDiff = false;
1213 protected $isDiffFromStable = false;
1314 protected $isMultiPageDiff = false;
@@ -1082,6 +1083,8 @@
10831084 # RevisionReviewForm will fetch them as needed however.
10841085 if ( $this->out->getRevisionId() == $rev->getId() ) {
10851086 $form->setIncludeVersions( $this->out->getTemplateIds(), $this->out->getImageTimeKeys() );
 1087+ } elseif ( $this->oldRevIncludes ) {
 1088+ $form->setIncludeVersions( $this->oldRevIncludes[0], $this->oldRevIncludes[1] );
10861089 }
10871090 list( $html, $status ) = $form->getHtml();
10881091 # Diff action: place the form at the top of the page
@@ -1372,6 +1375,7 @@
13731376 $changeList = self::fetchTemplateChanges( $srev, $incs[0] );
13741377 # Add a list of links to each changed file...
13751378 $changeList = array_merge( $changeList, self::fetchFileChanges( $srev, $incs[1] ) );
 1379+ $this->oldRevIncludes = $incs; // process cache
13761380 }
13771381 # If there are pending revs or templates/files changes, notify the user...
13781382 if ( $this->article->revsArePending() || count( $changeList ) ) {

Follow-up revisions

RevisionCommit summaryAuthorDate
r89196* Fixes for loop in getRevIncludes() from r88821...aaron01:06, 31 May 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r88740* Enumerate the specific templates/files that changed on review diffs...aaron19:51, 24 May 2011

Status & tagging log