Aaron Schulz has uploaded a new change for review.
https://gerrit.wikimedia.org/r/205528
Change subject: [WIP] Made loadState() generally use DB slaves
......................................................................
[WIP] Made loadState() generally use DB slaves
* Also added CAS logic similar to the User class
Change-Id: I60468efc77ff64b957aa098debbbc0d6f0f591f1
---
M includes/CentralAuthUser.php
1 file changed, 57 insertions(+), 15 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CentralAuth
refs/changes/28/205528/1
diff --git a/includes/CentralAuthUser.php b/includes/CentralAuthUser.php
old mode 100644
new mode 100755
index 325d909..bff9e5b
--- a/includes/CentralAuthUser.php
+++ b/includes/CentralAuthUser.php
@@ -17,13 +17,15 @@
*/
/*private*/ var $mName;
/*private*/ var $mStateDirty = false;
- /*private*/ var $mVersion = 5;
+ /*private*/ var $mVersion = 6;
/*private*/ var $mDelayInvalidation = 0;
var $mAttachedArray, $mEmail, $mEmailAuthenticated, $mHomeWiki,
$mHidden, $mLocked, $mAttachedList, $mAuthenticationTimestamp;
var $mGroups, $mRights, $mPassword, $mAuthToken, $mSalt, $mGlobalId,
$mFromMaster, $mIsAttached, $mRegistration, $mGlobalEditCount;
var $mBeingRenamed, $mBeingRenamedArray;
protected $mAttachedInfo;
+
+ protected $mCasToken;
static $mCacheVars = array(
'mGlobalId',
@@ -44,6 +46,7 @@
# avoid unserialize() overhead
'mAttachedList',
+ 'mCasToken',
'mVersion',
);
@@ -84,9 +87,11 @@
*/
public static function getCentralDB() {
global $wgCentralAuthDatabase, $wgCentralAuthReadOnly;
+
if ( $wgCentralAuthReadOnly ) {
throw new CentralAuthReadOnlyError();
}
+
return wfGetLB( $wgCentralAuthDatabase )->getConnection(
DB_MASTER, array(),
$wgCentralAuthDatabase );
}
@@ -98,12 +103,23 @@
*/
public static function getCentralSlaveDB() {
global $wgCentralAuthDatabase;
- return wfGetLB( $wgCentralAuthDatabase )->getConnection(
DB_SLAVE, 'centralauth',
- $wgCentralAuthDatabase );
+
+ return wfGetLB( $wgCentralAuthDatabase )->getConnection(
+ DB_SLAVE, 'centralauth', $wgCentralAuthDatabase );
+ }
+
+ /**
+ * @return bool hasOrMadeRecentMasterChanges() on the central load
balancer
+ */
+ protected static function centralLBHasRecentMasterChanges() {
+ global $wgCentralAuthDatabase;
+
+ return wfGetLB( $wgCentralAuthDatabase
)->hasOrMadeRecentMasterChanges();
}
public static function waitForSlaves() {
global $wgCentralAuthDatabase;
+
wfWaitForSlaves( false, $wgCentralAuthDatabase );
}
@@ -172,6 +188,7 @@
unset( $this->mAttachedArray );
unset( $this->mAttachedList );
unset( $this->mHomeWiki );
+ unset( $this->mCasToken );
}
/**
@@ -200,16 +217,20 @@
wfDebugLog( 'CentralAuthVerbose', "Loading state for global
user {$this->mName} from DB" );
- // Get the master. We want to make sure we've got up to date
information
- // since we're caching it.
- $dbw = self::getCentralDB();
+ if ( self::centralLBHasRecentMasterChanges() ) {
+ $db = self::getCentralDB();
+ $from = 'master';
+ } else {
+ $db = self::getCentralSlaveDB();
+ $from = 'slave';
+ }
- $row = $dbw->selectRow(
+ $row = $db->selectRow(
array( 'globaluser', 'localuser' ),
array(
'gu_id', 'lu_wiki', 'gu_salt', 'gu_password',
'gu_auth_token',
'gu_locked', 'gu_hidden', 'gu_registration',
'gu_email',
- 'gu_email_authenticated', 'gu_home_db',
+ 'gu_email_authenticated', 'gu_home_db',
'gu_cas_token'
),
array( 'gu_name' => $this->mName ),
__METHOD__,
@@ -220,10 +241,10 @@
);
$renameUserStatus = new GlobalRenameUserStatus( $this->mName );
- $renameUser = $renameUserStatus->getNames( null, 'master' );
+ $renameUser = $renameUserStatus->getNames( null, $from );
$this->loadFromRow( $row, $renameUser, true );
- $this->saveToCache();
+ $this->saveToCache( $from );
}
/**
@@ -297,6 +318,7 @@
wfTimestampOrNull( TS_MW,
$row->gu_email_authenticated );
$this->mFromMaster = $fromMaster;
$this->mHomeWiki = $row->gu_home_db;
+ $this->mCasToken = $row->gu_cas_token;
} else {
$this->mGlobalId = 0;
$this->mIsAttached = false;
@@ -381,8 +403,10 @@
/**
* Save cachable data to memcached.
+ *
+ * @param string $from slave/master
*/
- protected function saveToCache() {
+ protected function saveToCache( $from = 'slave' ) {
global $wgMemc;
// Make sure the data is fresh
@@ -390,10 +414,12 @@
$this->resetState();
}
+ $ttl = ( $from === 'master' ) ? 86400 : 30;
+
$obj = $this->getCacheObject();
wfDebugLog( 'CentralAuthVerbose', "Saving user {$this->mName}
to cache." );
- $wgMemc->set( $this->getCacheKey(), $obj, 86400 );
- }
+ $wgMemc->set( $this->getCacheKey(), $obj, $ttl );
+ }
/**
* Return the global account ID number for this account, if it exists.
@@ -2495,6 +2521,8 @@
return;
}
+ $newCasToken = $this->mCasToken + 1;
+
$dbw = self::getCentralDB();
$dbw->update( 'globaluser',
array( # SET
@@ -2505,14 +2533,28 @@
'gu_hidden' => $this->getHiddenLevel(),
'gu_email' => $this->mEmail,
'gu_email_authenticated' =>
$dbw->timestampOrNull( $this->mAuthenticationTimestamp ),
- 'gu_home_db' => $this->getHomeWiki()
+ 'gu_home_db' => $this->getHomeWiki(),
+ 'gu_cas_token' => $newCasToken
),
array( # WHERE
- 'gu_id' => $this->mGlobalId
+ 'gu_id' => $this->mGlobalId,
+ 'gu_cas_token' => $this->mCasToken
),
__METHOD__
);
+ if ( !$dbw->affectedRows() ) {
+ // Maybe the problem was a missed cache update; clear
it to be safe
+ $this->invalidateCache();
+ // User was changed in the meantime or loaded with
stale data
+ MWExceptionHandler::logException( new MWException(
+ "CAS update failed on gu_cas_token for user ID
'{$this->mGlobalId}';" .
+ "the version of the user to be saved is older
than the current version."
+ ) );
+ return;
+ }
+
+ $this->mCasToken = $newCasToken;
$this->invalidateCache();
}
--
To view, visit https://gerrit.wikimedia.org/r/205528
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I60468efc77ff64b957aa098debbbc0d6f0f591f1
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CentralAuth
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits