$data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
} elseif ( $from === self::READ_NORMAL ) {
$data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle );
- // Use a "last rev inserted" timestamp key to diminish 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 ) ) {
- $from = self::READ_LATEST;
- $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
- }
+ if ( !$data
+ && wfGetLB()->getServerCount() > 1
+ && wfGetLB()->hasOrMadeRecentMasterChanges()
+ ) {
+ $from = self::READ_LATEST;
+ $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
}
} else {
// No idea from where the caller got this data, assume slave database.
}
}
- /**
- * Get the cached timestamp for the last time the page changed.
- * This is only used to help handle slave lag by comparing to page_touched.
- * @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.
- * This is only used to help handle slave lag by comparing to page_touched.
- * @param string $timestamp
- * @return void
- */
- public function setCachedLastEditTime( $timestamp ) {
- global $wgMemc;
- $key = wfMemcKey( 'page-lastedit', md5( $this->mTitle->getPrefixedDBkey() ) );
- $wgMemc->set( $key, wfTimestamp( TS_MW, $timestamp ), 60 * 15 );
- }
-
/**
* Determine whether a page would be suitable for being counted as an
* article in the site_stats table based on the title & its content
}
// Update newtalk / watchlist notification status
- $user->clearNotification( $this->mTitle, $oldid );
+ try {
+ $user->clearNotification( $this->mTitle, $oldid );
+ } catch ( DBError $e ) {
+ // Avoid outage if the master is not reachable
+ MWExceptionHandler::logException( $e );
+ }
}
/**
* @return bool
*/
public function doPurge() {
- global $wgUseSquid;
-
if ( !Hooks::run( 'ArticlePurge', array( &$this ) ) ) {
return false;
}
- // Invalidate the cache
- $this->mTitle->invalidateCache();
-
- if ( $wgUseSquid ) {
- // Commit the transaction before the purge is sent
- $dbw = wfGetDB( DB_MASTER );
- $dbw->commit( __METHOD__ );
-
- // Send purge
- $update = SquidUpdate::newSimplePurge( $this->mTitle );
- $update->doUpdate();
- }
+ $title = $this->mTitle;
+ wfGetDB( DB_MASTER )->onTransactionIdle( function() use ( $title ) {
+ global $wgUseSquid;
+ // Invalidate the cache in auto-commit mode
+ $title->invalidateCache();
+ if ( $wgUseSquid ) {
+ // Send purge now that page_touched update was committed above
+ $update = SquidUpdate::newSimplePurge( $title );
+ $update->doUpdate();
+ }
+ } );
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
// @todo move this logic to MessageCache
-
if ( $this->exists() ) {
// NOTE: use transclusion text for messages.
// This is consistent with MessageCache::getMsgFromNamespace()
MessageCache::singleton()->replace( $this->mTitle->getDBkey(), $text );
}
+
return true;
}
if ( $result ) {
$this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect );
$this->setLastEdit( $revision );
- $this->setCachedLastEditTime( $now );
$this->mLatest = $revision->getId();
$this->mIsRedirect = (bool)$rt;
// Update the LinkCache.
$baseRevId = null;
if ( $edittime && $sectionId !== 'new' ) {
- $dbw = wfGetDB( DB_MASTER );
- $rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime );
+ $dbr = wfGetDB( DB_SLAVE );
+ $rev = Revision::loadFromTimestamp( $dbr, $this->mTitle, $edittime );
+ // Try the master if this thread may have just added it.
+ // This could be abstracted into a Revision method, but we don't want
+ // to encourage loading of revisions by timestamp.
+ if ( !$rev
+ && wfGetLB()->getServerCount() > 1
+ && wfGetLB()->hasOrMadeRecentMasterChanges()
+ ) {
+ $dbw = wfGetDB( DB_MASTER );
+ $rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime );
+ }
if ( $rev ) {
$baseRevId = $rev->getId();
}
if ( is_null( $baseRevId ) || $sectionId === 'new' ) {
$oldContent = $this->getContent();
} else {
- // TODO: try DB_SLAVE first
- $dbw = wfGetDB( DB_MASTER );
- $rev = Revision::loadFromId( $dbw, $baseRevId );
-
+ $rev = Revision::newFromId( $baseRevId );
if ( !$rev ) {
wfDebug( __METHOD__ . " asked for bogus section (page: " .
$this->getId() . "; section: $sectionId)\n" );
}
// The edit may have already been prepared via api.php?action=stashedit
- $cachedEdit = $useCache && $wgAjaxEditStash
+ $cachedEdit = $useCache && $wgAjaxEditStash && !$user->isAllowed( 'bot' )
? ApiStashEdit::checkCache( $this->getTitle(), $content, $user )
: false;
$dbw = wfGetDB( DB_MASTER );
foreach ( $restrictionTypes as $action ) {
- if ( !isset( $expiry[$action] ) ) {
- $expiry[$action] = $dbw->getInfinity();
+ if ( !isset( $expiry[$action] ) || $expiry[$action] === $dbw->getInfinity() ) {
+ $expiry[$action] = 'infinity';
}
if ( !isset( $limit[$action] ) ) {
$limit[$action] = '';
*/
protected function formatExpiry( $expiry ) {
global $wgContLang;
- $dbr = wfGetDB( DB_SLAVE );
- $encodedExpiry = $dbr->encodeExpiry( $expiry );
- if ( $encodedExpiry != 'infinity' ) {
+ if ( $expiry != 'infinity' ) {
return wfMessage(
'protect-expiring',
$wgContLang->timeanddate( $expiry, false, false ),