return false;
}
- global $wgMemc;
-
$limits = $wgRateLimits[$action];
$keys = array();
$id = $this->getId();
$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 ) {
} 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 );
}
}
const ERROR_UNCACHEABLE = 'uncacheable';
public function execute() {
- global $wgMemc;
+ $cache = ObjectCache::getLocalClusterInstance();
$user = $this->getUser();
$params = $this->extractRequestParams();
// 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 {
* @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 );
);
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;
* 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
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
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 {
* @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 ) {
* @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();
# 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 );
}
}
}
* @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() );
}
/**
* @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
$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();
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;
}
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;
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 ) ) {
* @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(
$lang->getCode(),
$this->getName()
);
- $obj = $wgMemc->get( $key );
+ $obj = $cache->get( $key );
if ( $obj ) {
wfDebug( "success!\n" );
}
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;
}
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
* @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;
}
} 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;
}
* @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' );
* @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;
}
* @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 ) ) {
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 ) ) {
} 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 );
}
}
* @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;
$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;
}
* @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 );
}
/**
}
function processLogin() {
- global $wgMemc, $wgLang, $wgSecureLogin, $wgPasswordAttemptThrottle,
- $wgInvalidPasswordReset;
+ global $wgLang, $wgSecureLogin, $wgPasswordAttemptThrottle, $wgInvalidPasswordReset;
+ $cache = ObjectCache::getLocalClusterInstance();
$authRes = $this->authenticateUserData();
switch ( $authRes ) {
case self::SUCCESS:
// 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