From eca50fb4b805495e6e946dc5e6a3c9a8f25357c9 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Mon, 25 Jul 2011 19:24:43 +0000 Subject: [PATCH] Follow-up r79518: added getCachedLastEditTime/getCachedLastEditTime methods to WikiPage and check them in loadPageData() to see if we should hit the master. This should lower the risk of stale data (by not just relying on cookie/session master position waiting). --- includes/WikiPage.php | 46 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/includes/WikiPage.php b/includes/WikiPage.php index f6551aabfe..10b4809bd5 100644 --- a/includes/WikiPage.php +++ b/includes/WikiPage.php @@ -350,19 +350,28 @@ class WikiPage extends Page { * A DB query result object or... * "fromdb" to get from a slave DB or... * "fromdbmaster" to get from the master DB + * @return void */ public function loadPageData( $data = 'fromdb' ) { - if ( $data === 'fromdb' || $data === 'fromdbmaster' ) { - $db = ( $data == 'fromdbmaster' ) - ? wfGetDB( DB_MASTER ) - : wfGetDB( DB_SLAVE ); - $data = $this->pageDataFromTitle( $db, $this->mTitle ); + if ( $data === 'fromdbmaster' ) { + $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle ); + } elseif ( $data === 'fromdb' ) { // slave + $data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle ); + # Use a "last rev inserted" timestamp key to dimish the issue of slave lag. + # Note that DB also stores the master position in the session and checks it. + $touched = $this->getCachedLastEditTime(); + if ( $touched ) { // key set + if ( !$data || $touched > wfTimestamp( TS_MW, $data->page_touched ) ) { + $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle ); + } + } } $lc = LinkCache::singleton(); if ( $data ) { - $lc->addGoodLinkObj( $data->page_id, $this->mTitle, $data->page_len, $data->page_is_redirect, $data->page_latest ); + $lc->addGoodLinkObj( $data->page_id, $this->mTitle, + $data->page_len, $data->page_is_redirect, $data->page_latest ); $this->mTitle->loadFromRow( $data ); @@ -814,10 +823,11 @@ class WikiPage extends Page { $conditions['page_latest'] = $lastRevision; } + $now = wfTimestampNow(); $dbw->update( 'page', array( /* SET */ 'page_latest' => $revision->getId(), - 'page_touched' => $dbw->timestamp(), + 'page_touched' => $dbw->timestamp( $now ), 'page_is_new' => ( $lastRevision === 0 ) ? 1 : 0, 'page_is_redirect' => $rt !== null ? 1 : 0, 'page_len' => strlen( $text ), @@ -828,12 +838,34 @@ class WikiPage extends Page { $result = $dbw->affectedRows() != 0; if ( $result ) { $this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect ); + $this->setCachedLastEditTime( $now ); } wfProfileOut( __METHOD__ ); return $result; } + /** + * Get the cached timestamp for the last time the page changed + * @return string MW timestamp + */ + protected function getCachedLastEditTime() { + global $wgMemc; + $key = wfMemcKey( 'page-lastedit', md5( $this->mTitle->getPrefixedDBkey() ) ); + return $wgMemc->get( $key ); + } + + /** + * Set the cached timestamp for the last time the page changed + * @param $timestamp string + * @return void + */ + protected function setCachedLastEditTime( $timestamp ) { + global $wgMemc; + $key = wfMemcKey( 'page-lastedit', md5( $this->mTitle->getPrefixedDBkey() ) ); + $wgMemc->set( $key, wfTimestamp( TS_MW, $timestamp ), 60*15 ); + } + /** * Add row to the redirect table if this is a redirect, remove otherwise. * -- 2.20.1