From c1094ba98763f22488a21dac5e65218f6b146482 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 3 Oct 2006 22:30:40 +0000 Subject: [PATCH] * Do fewer unnecessary full writes of user rows; only update user_touched for watch/unwatch, group membership change, and login operations --- RELEASE-NOTES | 2 ++ includes/Article.php | 2 -- includes/SpecialUserlogin.php | 8 ++++-- includes/User.php | 54 ++++++++++++++++++++++++++++------- 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index eac2f15bd3..c253ff3f3f 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -255,6 +255,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN * (bug 6889) PHP notices in thumb.php with missing params * Cleaner error behavior on thumb.php with invalid page selection * (bug 6617) Validate timestamps on Special:Undelete +* Do fewer unnecessary full writes of user rows; only update user_touched + for watch/unwatch, group membership change, and login operations == Languages updated == diff --git a/includes/Article.php b/includes/Article.php index 4764d469dc..5f81730074 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -1464,7 +1464,6 @@ class Article { if (wfRunHooks('WatchArticle', array(&$wgUser, &$this))) { $wgUser->addWatch( $this->mTitle ); - $wgUser->saveSettings(); return wfRunHooks('WatchArticleComplete', array(&$wgUser, &$this)); } @@ -1512,7 +1511,6 @@ class Article { if (wfRunHooks('UnwatchArticle', array(&$wgUser, &$this))) { $wgUser->removeWatch( $this->mTitle ); - $wgUser->saveSettings(); return wfRunHooks('UnwatchArticleComplete', array(&$wgUser, &$this)); } diff --git a/includes/SpecialUserlogin.php b/includes/SpecialUserlogin.php index 5e5f7b0419..cc7339f87b 100644 --- a/includes/SpecialUserlogin.php +++ b/includes/SpecialUserlogin.php @@ -365,9 +365,13 @@ class LoginForm { { case self::SUCCESS: # We've verified now, update the real record - $wgUser->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 ); + if( (bool)$this->mRemember != (bool)$wgUser->getOption( 'rememberpassword' ) ) { + $wgUser->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 ); + $wgUser->saveSettings(); + } else { + $wgUser->invalidateCache(); + } $wgUser->setCookies(); - $wgUser->saveSettings(); if( $this->hasSessionCookie() ) { return $this->successfulLogin( wfMsg( 'loginsuccess', $wgUser->getName() ) ); diff --git a/includes/User.php b/includes/User.php index 4913de89d2..7dc4689731 100644 --- a/includes/User.php +++ b/includes/User.php @@ -1094,16 +1094,49 @@ class User { } } $this->invalidateCache(); - $this->saveSettings(); + } + } + + /** + * Generate a current or new-future timestamp to be stored in the + * user_touched field when we update things. + */ + private static function newTouchedTimestamp() { + global $wgClockSkewFudge; + return wfTimestamp( TS_MW, time() + $wgClockSkewFudge ); + } + + /** + * Clear user data from memcached. + * Use after applying fun updates to the database; caller's + * responsibility to update user_touched if appropriate. + * + * Called implicitly from invalidateCache() and saveSettings(). + */ + private function clearUserCache() { + if( $this->mId ) { + global $wgMemc, $wgDBname; + $wgMemc->delete( "$wgDBname:user:id:$this->mId" ); } } + /** + * Immediately touch the user data cache for this account. + * Updates user_touched field, and removes account data from memcached + * for reload on the next hit. + */ function invalidateCache() { - global $wgClockSkewFudge; - $this->loadFromDatabase(); - $this->mTouched = wfTimestamp(TS_MW, time() + $wgClockSkewFudge ); - # Don't forget to save the options after this or - # it won't take effect! + if( $this->mId ) { + $this->mTouched = self::newTouchedTimestamp(); + + $dbw =& wfGetDB( DB_MASTER ); + $dbw->update( 'user', + array( 'user_touched' => $dbw->timestamp( $this->mTouched ) ), + array( 'user_id' => $this->mId ), + __METHOD__ ); + + $this->clearUserCache(); + } } function validateCache( $timestamp ) { @@ -1252,7 +1285,6 @@ class User { $val = str_replace( "\r", "\n", $val ); $val = str_replace( "\n", " ", $val ); $this->mOptions[$oname] = $val; - $this->invalidateCache(); } function getRights() { @@ -1303,7 +1335,6 @@ class User { $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups() ); $this->invalidateCache(); - $this->saveSettings(); } /** @@ -1324,7 +1355,6 @@ class User { $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups() ); $this->invalidateCache(); - $this->saveSettings(); } @@ -1579,13 +1609,15 @@ class User { /** * Save object settings into database + * @fixme Only rarely do all these fields need to be set! */ function saveSettings() { - global $wgMemc, $wgDBname; $fname = 'User::saveSettings'; if ( wfReadOnly() ) { return; } if ( 0 == $this->mId ) { return; } + + $this->mTouched = self::newTouchedTimestamp(); $dbw =& wfGetDB( DB_MASTER ); $dbw->update( 'user', @@ -1603,7 +1635,7 @@ class User { 'user_id' => $this->mId ), $fname ); - $wgMemc->delete( "$wgDBname:user:id:$this->mId" ); + $this->clearUserCache(); } -- 2.20.1