From 92bbfd5ea63739f97d2449c7727b7da29f802267 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Mon, 26 Oct 2015 00:41:05 -0700 Subject: [PATCH] Migrate more callers away from $wgMemc Callers should use more expliciy lazy-loaded cache factory methods. Change-Id: Ifa0bf389720a09a931ee6466b993f787d83a09a7 --- includes/User.php | 10 ++++---- includes/api/ApiStashEdit.php | 29 +++++++++++----------- includes/cache/FileCacheBase.php | 16 ++++++------ includes/filerepo/ForeignAPIRepo.php | 8 +++--- includes/filerepo/file/File.php | 19 ++++++++------ includes/filerepo/file/ForeignAPIFile.php | 8 +++--- includes/jobqueue/JobQueueDB.php | 7 +++--- includes/jobqueue/JobQueueGroup.php | 14 +++++------ includes/specials/SpecialUserlogin.php | 30 ++++++++++++----------- 9 files changed, 72 insertions(+), 69 deletions(-) diff --git a/includes/User.php b/includes/User.php index e1c9e358f1..1727a4a5c7 100644 --- a/includes/User.php +++ b/includes/User.php @@ -1739,8 +1739,6 @@ class User implements IDBAccessObject { return false; } - global $wgMemc; - $limits = $wgRateLimits[$action]; $keys = array(); $id = $this->getId(); @@ -1795,11 +1793,13 @@ class User implements IDBAccessObject { $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $userLimit; } + $cache = ObjectCache::getLocalClusterInstance(); + $triggered = false; foreach ( $keys as $key => $limit ) { list( $max, $period ) = $limit; $summary = "(limit $max in {$period}s)"; - $count = $wgMemc->get( $key ); + $count = $cache->get( $key ); // Already pinged? if ( $count ) { if ( $count >= $max ) { @@ -1812,11 +1812,11 @@ class User implements IDBAccessObject { } else { wfDebug( __METHOD__ . ": adding record for $key $summary\n" ); if ( $incrBy > 0 ) { - $wgMemc->add( $key, 0, intval( $period ) ); // first ping + $cache->add( $key, 0, intval( $period ) ); // first ping } } if ( $incrBy > 0 ) { - $wgMemc->incr( $key, $incrBy ); + $cache->incr( $key, $incrBy ); } } diff --git a/includes/api/ApiStashEdit.php b/includes/api/ApiStashEdit.php index e87fc97a19..ebddd51734 100644 --- a/includes/api/ApiStashEdit.php +++ b/includes/api/ApiStashEdit.php @@ -39,7 +39,7 @@ class ApiStashEdit extends ApiBase { const ERROR_UNCACHEABLE = 'uncacheable'; public function execute() { - global $wgMemc; + $cache = ObjectCache::getLocalClusterInstance(); $user = $this->getUser(); $params = $this->extractRequestParams(); @@ -111,11 +111,10 @@ class ApiStashEdit extends ApiBase { // De-duplicate requests on the same key if ( $user->pingLimiter( 'stashedit' ) ) { $status = 'ratelimited'; - } elseif ( $wgMemc->lock( $key, 0, 30 ) ) { + } elseif ( $cache->lock( $key, 0, 30 ) ) { /** @noinspection PhpUnusedLocalVariableInspection */ - $unlocker = new ScopedCallback( function() use ( $key ) { - global $wgMemc; - $wgMemc->unlock( $key ); + $unlocker = new ScopedCallback( function() use ( $cache, $key ) { + $cache->unlock( $key ); } ); $status = self::parseAndStash( $page, $content, $user ); } else { @@ -133,7 +132,7 @@ class ApiStashEdit extends ApiBase { * @since 1.25 */ public static function parseAndStash( WikiPage $page, Content $content, User $user ) { - global $wgMemc; + $cache = ObjectCache::getLocalClusterInstance(); $format = $content->getDefaultFormat(); $editInfo = $page->prepareContentForEdit( $content, null, $user, $format, false ); @@ -146,7 +145,7 @@ class ApiStashEdit extends ApiBase { ); if ( $stashInfo ) { - $ok = $wgMemc->set( $key, $stashInfo, $ttl ); + $ok = $cache->set( $key, $stashInfo, $ttl ); if ( $ok ) { wfDebugLog( 'StashEdit', "Cached parser output for key '$key'." ); return self::ERROR_NONE; @@ -173,7 +172,7 @@ class ApiStashEdit extends ApiBase { * will do nothing. Provided the values are cacheable, they will be stored * in memcached so that final edit submission might make use of them. * - * @param Article|WikiPage $page Page title + * @param Page|Article|WikiPage $page Page title * @param Content $content Proposed page content * @param Content $pstContent The result of preSaveTransform() on $content * @param ParserOutput $pOut The result of getParserOutput() on $pstContent @@ -186,7 +185,7 @@ class ApiStashEdit extends ApiBase { Page $page, Content $content, Content $pstContent, ParserOutput $pOut, ParserOptions $pstOpts, ParserOptions $pOpts, $timestamp ) { - global $wgMemc; + $cache = ObjectCache::getLocalClusterInstance(); // getIsPreview() controls parser function behavior that references things // like user/revision that don't exists yet. The user/text should already @@ -219,7 +218,7 @@ class ApiStashEdit extends ApiBase { return false; } - $ok = $wgMemc->set( $key, $stashInfo, $ttl ); + $ok = $cache->set( $key, $stashInfo, $ttl ); if ( !$ok ) { wfDebugLog( 'StashEdit', "Failed to cache preview parser output for key '$key'." ); } else { @@ -247,17 +246,17 @@ class ApiStashEdit extends ApiBase { * @return stdClass|bool Returns false on cache miss */ public static function checkCache( Title $title, Content $content, User $user ) { - global $wgMemc; + $cache = ObjectCache::getLocalClusterInstance(); $key = self::getStashKey( $title, $content, $user ); - $editInfo = $wgMemc->get( $key ); + $editInfo = $cache->get( $key ); if ( !is_object( $editInfo ) ) { $start = microtime( true ); // We ignore user aborts and keep parsing. Block on any prior parsing // so as to use it's results and make use of the time spent parsing. - if ( $wgMemc->lock( $key, 30, 30 ) ) { - $editInfo = $wgMemc->get( $key ); - $wgMemc->unlock( $key ); + if ( $cache->lock( $key, 30, 30 ) ) { + $editInfo = $cache->get( $key ); + $cache->unlock( $key ); } $sec = microtime( true ) - $start; if ( $sec > .01 ) { diff --git a/includes/cache/FileCacheBase.php b/includes/cache/FileCacheBase.php index 5632596a43..360420b615 100644 --- a/includes/cache/FileCacheBase.php +++ b/includes/cache/FileCacheBase.php @@ -235,8 +235,8 @@ abstract class FileCacheBase { * @return void */ public function incrMissesRecent( WebRequest $request ) { - global $wgMemc; if ( mt_rand( 0, self::MISS_FACTOR - 1 ) == 0 ) { + $cache = ObjectCache::getLocalClusterInstance(); # Get a large IP range that should include the user even if that # person's IP address changes $ip = $request->getIP(); @@ -249,17 +249,17 @@ abstract class FileCacheBase { # Bail out if a request already came from this range... $key = wfMemcKey( get_class( $this ), 'attempt', $this->mType, $this->mKey, $ip ); - if ( $wgMemc->get( $key ) ) { + if ( $cache->get( $key ) ) { return; // possibly the same user } - $wgMemc->set( $key, 1, self::MISS_TTL_SEC ); + $cache->set( $key, 1, self::MISS_TTL_SEC ); # Increment the number of cache misses... $key = $this->cacheMissKey(); - if ( $wgMemc->get( $key ) === false ) { - $wgMemc->set( $key, 1, self::MISS_TTL_SEC ); + if ( $cache->get( $key ) === false ) { + $cache->set( $key, 1, self::MISS_TTL_SEC ); } else { - $wgMemc->incr( $key ); + $cache->incr( $key ); } } } @@ -269,9 +269,9 @@ abstract class FileCacheBase { * @return int */ public function getMissesRecent() { - global $wgMemc; + $cache = ObjectCache::getLocalClusterInstance(); - return self::MISS_FACTOR * $wgMemc->get( $this->cacheMissKey() ); + return self::MISS_FACTOR * $cache->get( $this->cacheMissKey() ); } /** diff --git a/includes/filerepo/ForeignAPIRepo.php b/includes/filerepo/ForeignAPIRepo.php index 4ffbf4add2..3747e60f31 100644 --- a/includes/filerepo/ForeignAPIRepo.php +++ b/includes/filerepo/ForeignAPIRepo.php @@ -329,7 +329,7 @@ class ForeignAPIRepo extends FileRepo { * @return bool|string */ function getThumbUrlFromCache( $name, $width, $height, $params = "" ) { - global $wgMemc; + $cache = ObjectCache::getMainWANInstance(); // We can't check the local cache using FileRepo functions because // we override fileExistsBatch(). We have to use the FileBackend directly. $backend = $this->getBackend(); // convenience @@ -342,7 +342,7 @@ class ForeignAPIRepo extends FileRepo { $sizekey = "$width:$height:$params"; /* Get the array of urls that we already know */ - $knownThumbUrls = $wgMemc->get( $key ); + $knownThumbUrls = $cache->get( $key ); if ( !$knownThumbUrls ) { /* No knownThumbUrls for this file */ $knownThumbUrls = array(); @@ -388,7 +388,7 @@ class ForeignAPIRepo extends FileRepo { if ( $remoteModified < $modified && $diff < $this->fileCacheExpiry ) { /* Use our current and already downloaded thumbnail */ $knownThumbUrls[$sizekey] = $localUrl; - $wgMemc->set( $key, $knownThumbUrls, $this->apiThumbCacheExpiry ); + $cache->set( $key, $knownThumbUrls, $this->apiThumbCacheExpiry ); return $localUrl; } @@ -410,7 +410,7 @@ class ForeignAPIRepo extends FileRepo { return $foreignUrl; } $knownThumbUrls[$sizekey] = $localUrl; - $wgMemc->set( $key, $knownThumbUrls, $this->apiThumbCacheExpiry ); + $cache->set( $key, $knownThumbUrls, $this->apiThumbCacheExpiry ); wfDebug( __METHOD__ . " got local thumb $localUrl, saving to cache \n" ); return $localUrl; diff --git a/includes/filerepo/file/File.php b/includes/filerepo/file/File.php index 588ae6b2fd..64cc887ef9 100644 --- a/includes/filerepo/file/File.php +++ b/includes/filerepo/file/File.php @@ -1137,6 +1137,7 @@ abstract class File implements IDBAccessObject { if ( !$thumb ) { // bad params? $thumb = false; } elseif ( $thumb->isError() ) { // transform error + /** @var $thumb MediaTransformError */ $this->lastError = $thumb->toText(); // Ignore errors if requested if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) { @@ -2019,15 +2020,19 @@ abstract class File implements IDBAccessObject { * @return string */ function getDescriptionText( $lang = false ) { - global $wgMemc, $wgLang; + global $wgLang; + if ( !$this->repo || !$this->repo->fetchDescription ) { return false; } - if ( !$lang ) { - $lang = $wgLang; - } + + $lang = $lang ?: $wgLang; + $renderUrl = $this->repo->getDescriptionRenderUrl( $this->getName(), $lang->getCode() ); if ( $renderUrl ) { + $cache = ObjectCache::getMainWANInstance(); + + $key = null; if ( $this->repo->descriptionCacheExpiry > 0 ) { wfDebug( "Attempting to get the description from cache..." ); $key = $this->repo->getLocalCacheKey( @@ -2036,7 +2041,7 @@ abstract class File implements IDBAccessObject { $lang->getCode(), $this->getName() ); - $obj = $wgMemc->get( $key ); + $obj = $cache->get( $key ); if ( $obj ) { wfDebug( "success!\n" ); @@ -2046,8 +2051,8 @@ abstract class File implements IDBAccessObject { } wfDebug( "Fetching shared description from $renderUrl\n" ); $res = Http::get( $renderUrl, array(), __METHOD__ ); - if ( $res && $this->repo->descriptionCacheExpiry > 0 ) { - $wgMemc->set( $key, $res, $this->repo->descriptionCacheExpiry ); + if ( $res && $key ) { + $cache->set( $key, $res, $this->repo->descriptionCacheExpiry ); } return $res; diff --git a/includes/filerepo/file/ForeignAPIFile.php b/includes/filerepo/file/ForeignAPIFile.php index 3c78290c27..cad806d6a3 100644 --- a/includes/filerepo/file/ForeignAPIFile.php +++ b/includes/filerepo/file/ForeignAPIFile.php @@ -334,22 +334,20 @@ class ForeignAPIFile extends File { } function purgeDescriptionPage() { - global $wgMemc, $wgContLang; + global $wgContLang; $url = $this->repo->getDescriptionRenderUrl( $this->getName(), $wgContLang->getCode() ); $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', md5( $url ) ); - $wgMemc->delete( $key ); + ObjectCache::getMainWANInstance()->delete( $key ); } /** * @param array $options */ function purgeThumbnails( $options = array() ) { - global $wgMemc; - $key = $this->repo->getLocalCacheKey( 'ForeignAPIRepo', 'ThumbUrl', $this->getName() ); - $wgMemc->delete( $key ); + ObjectCache::getMainWANInstance()->delete( $key ); $files = $this->getThumbnails(); // Give media handler a chance to filter the purge list diff --git a/includes/jobqueue/JobQueueDB.php b/includes/jobqueue/JobQueueDB.php index 7907614b89..6ecfaf4001 100644 --- a/includes/jobqueue/JobQueueDB.php +++ b/includes/jobqueue/JobQueueDB.php @@ -144,15 +144,13 @@ class JobQueueDB extends JobQueue { * @throws MWException */ protected function doGetAbandonedCount() { - global $wgMemc; - if ( $this->claimTTL <= 0 ) { return 0; // no acknowledgements } $key = $this->getCacheKey( 'abandonedcount' ); - $count = $wgMemc->get( $key ); + $count = $this->cache->get( $key ); if ( is_int( $count ) ) { return $count; } @@ -170,7 +168,8 @@ class JobQueueDB extends JobQueue { } catch ( DBError $e ) { $this->throwDBException( $e ); } - $wgMemc->set( $key, $count, self::CACHE_TTL_SHORT ); + + $this->cache->set( $key, $count, self::CACHE_TTL_SHORT ); return $count; } diff --git a/includes/jobqueue/JobQueueGroup.php b/includes/jobqueue/JobQueueGroup.php index 5bd1cc94a8..a702d59049 100644 --- a/includes/jobqueue/JobQueueGroup.php +++ b/includes/jobqueue/JobQueueGroup.php @@ -286,18 +286,17 @@ class JobQueueGroup { * @since 1.23 */ public function queuesHaveJobs( $type = self::TYPE_ANY ) { - global $wgMemc; - $key = wfMemcKey( 'jobqueue', 'queueshavejobs', $type ); + $cache = ObjectCache::getLocalClusterInstance(); - $value = $wgMemc->get( $key ); + $value = $cache->get( $key ); if ( $value === false ) { $queues = $this->getQueuesWithJobs(); if ( $type == self::TYPE_DEFAULT ) { $queues = array_intersect( $queues, $this->getDefaultQueueTypes() ); } $value = count( $queues ) ? 'true' : 'false'; - $wgMemc->add( $key, $value, 15 ); + $cache->add( $key, $value, 15 ); } return ( $value === 'true' ); @@ -382,19 +381,20 @@ class JobQueueGroup { * @return mixed */ private function getCachedConfigVar( $name ) { - global $wgConf, $wgMemc; + global $wgConf; if ( $this->wiki === wfWikiID() ) { return $GLOBALS[$name]; // common case } else { + $cache = ObjectCache::getLocalClusterInstance(); list( $db, $prefix ) = wfSplitWikiID( $this->wiki ); $key = wfForeignMemcKey( $db, $prefix, 'configvalue', $name ); - $value = $wgMemc->get( $key ); // ('v' => ...) or false + $value = $cache->get( $key ); // ('v' => ...) or false if ( is_array( $value ) ) { return $value['v']; } else { $value = $wgConf->getConfig( $this->wiki, $name ); - $wgMemc->set( $key, array( 'v' => $value ), 86400 + mt_rand( 0, 86400 ) ); + $cache->set( $key, array( 'v' => $value ), 86400 + mt_rand( 0, 86400 ) ); return $value; } diff --git a/includes/specials/SpecialUserlogin.php b/includes/specials/SpecialUserlogin.php index 8facb35c41..8864b981a5 100644 --- a/includes/specials/SpecialUserlogin.php +++ b/includes/specials/SpecialUserlogin.php @@ -485,7 +485,7 @@ class LoginForm extends SpecialPage { * @return Status */ public function addNewAccountInternal() { - global $wgAuth, $wgMemc, $wgAccountCreationThrottle, $wgEmailConfirmToEdit; + global $wgAuth, $wgAccountCreationThrottle, $wgEmailConfirmToEdit; // If the user passes an invalid domain, something is fishy if ( !$wgAuth->validDomain( $this->mDomain ) ) { @@ -565,8 +565,9 @@ class LoginForm extends SpecialPage { return Status::newFatal( 'noname' ); } + $cache = ObjectCache::getLocalClusterInstance(); # Make sure the user does not exist already - $lock = $wgMemc->getScopedLock( wfGlobalCacheKey( 'account', md5( $this->mUsername ) ) ); + $lock = $cache->getScopedLock( wfGlobalCacheKey( 'account', md5( $this->mUsername ) ) ); if ( !$lock ) { return Status::newFatal( 'usernameinprogress' ); } elseif ( $u->idForName( User::READ_LOCKING ) ) { @@ -633,14 +634,14 @@ class LoginForm extends SpecialPage { } else { if ( ( $wgAccountCreationThrottle && $currentUser->isPingLimitable() ) ) { $key = wfMemcKey( 'acctcreate', 'ip', $ip ); - $value = $wgMemc->get( $key ); + $value = $cache->get( $key ); if ( !$value ) { - $wgMemc->set( $key, 0, 86400 ); + $cache->set( $key, 0, 86400 ); } if ( $value >= $wgAccountCreationThrottle ) { return Status::newFatal( 'acct_creation_throttle_hit', $wgAccountCreationThrottle ); } - $wgMemc->incr( $key ); + $cache->incr( $key ); } } @@ -869,7 +870,7 @@ class LoginForm extends SpecialPage { * @return bool|int The integer hit count or True if it is already at the limit */ public static function incLoginThrottle( $username ) { - global $wgPasswordAttemptThrottle, $wgMemc, $wgRequest; + global $wgPasswordAttemptThrottle, $wgRequest; $username = trim( $username ); // sanity $throttleCount = 0; @@ -878,11 +879,12 @@ class LoginForm extends SpecialPage { $count = $wgPasswordAttemptThrottle['count']; $period = $wgPasswordAttemptThrottle['seconds']; - $throttleCount = $wgMemc->get( $throttleKey ); + $cache = ObjectCache::getLocalClusterInstance(); + $throttleCount = $cache->get( $throttleKey ); if ( !$throttleCount ) { - $wgMemc->add( $throttleKey, 1, $period ); // start counter + $cache->add( $throttleKey, 1, $period ); // start counter } elseif ( $throttleCount < $count ) { - $wgMemc->incr( $throttleKey ); + $cache->incr( $throttleKey ); } elseif ( $throttleCount >= $count ) { return true; } @@ -897,11 +899,11 @@ class LoginForm extends SpecialPage { * @return void */ public static function clearLoginThrottle( $username ) { - global $wgMemc, $wgRequest; + global $wgRequest; $username = trim( $username ); // sanity $throttleKey = wfMemcKey( 'password-throttle', $wgRequest->getIP(), md5( $username ) ); - $wgMemc->delete( $throttleKey ); + ObjectCache::getLocalClusterInstance()->delete( $throttleKey ); } /** @@ -960,9 +962,9 @@ class LoginForm extends SpecialPage { } function processLogin() { - global $wgMemc, $wgLang, $wgSecureLogin, $wgPasswordAttemptThrottle, - $wgInvalidPasswordReset; + global $wgLang, $wgSecureLogin, $wgPasswordAttemptThrottle, $wgInvalidPasswordReset; + $cache = ObjectCache::getLocalClusterInstance(); $authRes = $this->authenticateUserData(); switch ( $authRes ) { case self::SUCCESS: @@ -984,7 +986,7 @@ class LoginForm extends SpecialPage { // Reset the throttle $request = $this->getRequest(); $key = wfMemcKey( 'password-throttle', $request->getIP(), md5( $this->mUsername ) ); - $wgMemc->delete( $key ); + $cache->delete( $key ); if ( $this->hasSessionCookie() || $this->mSkipCookieCheck ) { /* Replace the language object to provide user interface in -- 2.20.1