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

Reply via email to