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