Krinkle has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/273597

Change subject: [WIP] User: Simplify process cache by using WANCache 
getWithSetCallback
......................................................................

[WIP] User: Simplify process cache by using WANCache getWithSetCallback

Follows-up 7d67b4d9195346e133.

* Fix potential bug in previous implementation where clearing of
  cache was ignored within the process (e.g. as by saveSettings()).

* Fix potential bug where database options from DB_SLAVE were
  used in saveToCache(), even if the load was from DB_MASTER.

* Removes one public method, saveToCache(). It already had a noted
  that it shouldn't be called outside the class. It had two callers
  in extensions PluggableAuth and TwitterLogin.

* Remove obsolete note in docs/memcached.txt about the User
  object cache key. This hasn't been true since b3acd4f.

Change-Id: Ia7ab78ef22c24a7421ea25db1440e7267f0a725d
---
M docs/memcached.txt
M includes/user/User.php
2 files changed, 76 insertions(+), 72 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/97/273597/1

diff --git a/docs/memcached.txt b/docs/memcached.txt
index 55fa725..e914a3a 100644
--- a/docs/memcached.txt
+++ b/docs/memcached.txt
@@ -232,11 +232,4 @@
        Special:Recentchanges?action=purge&feed=atom,
        but note need $wgGroupPermissions[...]['purge'] permission.
 
-User:
-       key: $wgDBname:user:id:$sId
-       ex: wikidb:user:id:51
-       stores: instance of class User
-       set in: User::saveToCache()
-       cleared by: User::saveSettings(), User::clearSharedCache()
-
 ... more to come ...
diff --git a/includes/user/User.php b/includes/user/User.php
index c92c06b..85eea1b 100644
--- a/includes/user/User.php
+++ b/includes/user/User.php
@@ -417,8 +417,7 @@
                // Try cache (unless this needs data from the master DB).
                // NOTE: if this thread called saveSettings(), the cache was 
cleared.
                $latest = DBAccessObjectUtils::hasFlags( $flags, 
self::READ_LATEST );
-               if ( $latest || !$this->loadFromCache() ) {
-                       wfDebug( "User: cache miss for user {$this->mId}\n" );
+               if ( $latest ) {
                        // Load from DB (make sure this thread sees its own 
changes)
                        if ( wfGetLB()->hasOrMadeRecentMasterChanges() ) {
                                $flags |= self::READ_LATEST;
@@ -427,13 +426,87 @@
                                // Can't load from ID, user is anonymous
                                return false;
                        }
-                       $this->saveToCache();
+                       $data = $this->prepareCacheData();
+                       if ( $data ) {
+                               $cache = ObjectCache::getMainWANInstance();
+                               $cache->set(
+                                       $this->getCacheKey( $cache ),
+                                       $data,
+                                       $cache::TTL_HOUR,
+                                       Database::getCacheSetOptions( wfGetDB( 
DB_MASTER ) )
+                               );
+                       }
+               } else {
+                       $this->loadFromCache();
                }
 
                $this->mLoadedItems = true;
                $this->queryFlagsUsed = $flags;
 
                return true;
+       }
+
+       /**
+        * Load user data from shared cache, given mId has already been set.
+        *
+        * @return bool false if the ID does not exist or data is invalid, true 
otherwise
+        * @since 1.25
+        */
+       protected function loadFromCache() {
+               if ( $this->mId == 0 ) {
+                       $this->loadDefaults();
+                       return false;
+               }
+               $cache = ObjectCache::getMainWANInstance();
+               $data = $cache->getWithSetCallback(
+                       $this->getCacheKey( $cache ),
+                       $cache::TTL_HOUR,
+                       function ( $oldValue, &$ttl, array &$setOpts ) {
+                               $setOpts += Database::getCacheSetOptions( 
wfGetDB( DB_SLAVE ) );
+
+                               wfDebug( "User: cache miss for user 
{$this->mId}\n" );
+
+                               return $this->prepareCacheData();
+
+                       },
+                       array( 'pcTTL' => $cache::TTL_MINUTE )
+               );
+
+               if ( !is_array( $data ) || $data['mVersion'] < self::VERSION ) {
+                       // Object is expired
+                       return false;
+               }
+
+               // Restore from cache
+               foreach ( self::$mCacheVars as $name ) {
+                       $this->$name = $data[$name];
+               }
+
+               return true;
+       }
+
+       /**
+        * Prepare user data for the shared cache
+        * @return array|bool
+        * @since 1.27
+        */
+       protected function prepareCacheData() {
+               $this->load();
+               $this->loadGroups();
+               $this->loadOptions();
+
+               if ( $this->isAnon() ) {
+                       // Anonymous users are uncached
+                       return false;
+               }
+
+               $data = [];
+               foreach ( self::$mCacheVars as $name ) {
+                       $data[$name] = $this->$name;
+               }
+               $data['mVersion'] = self::VERSION;
+
+               return $data;
        }
 
        /**
@@ -453,68 +526,6 @@
         */
        protected function getCacheKey( WANObjectCache $cache ) {
                return $cache->makeGlobalKey( 'user', 'id', wfWikiID(), 
$this->mId );
-       }
-
-       /**
-        * Load user data from shared cache, given mId has already been set.
-        *
-        * @return bool false if the ID does not exist or data is invalid, true 
otherwise
-        * @since 1.25
-        */
-       protected function loadFromCache() {
-               if ( $this->mId == 0 ) {
-                       $this->loadDefaults();
-                       return false;
-               }
-
-               $cache = ObjectCache::getMainWANInstance();
-               $key = $this->getCacheKey( $cache );
-
-               $processCache = ObjectCache::getLocalServerInstance( 'hash' );
-               $data = $processCache->get( $key );
-               if ( !is_array( $data ) ) {
-                       $data = $cache->get( $key );
-                       if ( !is_array( $data ) || $data['mVersion'] < 
self::VERSION ) {
-                               // Object is expired
-                               return false;
-                       }
-                       $processCache->set( $key, $data );
-               }
-               wfDebug( "User: got user {$this->mId} from cache\n" );
-
-               // Restore from cache
-               foreach ( self::$mCacheVars as $name ) {
-                       $this->$name = $data[$name];
-               }
-
-               return true;
-       }
-
-       /**
-        * Save user data to the shared cache
-        *
-        * This method should not be called outside the User class
-        */
-       public function saveToCache() {
-               $this->load();
-               $this->loadGroups();
-               $this->loadOptions();
-
-               if ( $this->isAnon() ) {
-                       // Anonymous users are uncached
-                       return;
-               }
-
-               $data = [];
-               foreach ( self::$mCacheVars as $name ) {
-                       $data[$name] = $this->$name;
-               }
-               $data['mVersion'] = self::VERSION;
-               $opts = Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
-
-               $cache = ObjectCache::getMainWANInstance();
-               $key = $this->getCacheKey( $cache );
-               $cache->set( $key, $data, $cache::TTL_HOUR, $opts );
        }
 
        /** @name newFrom*() static factory methods */

-- 
To view, visit https://gerrit.wikimedia.org/r/273597
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia7ab78ef22c24a7421ea25db1440e7267f0a725d
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Krinkle <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to