function createCache() { if (!isset($this->cache)) { global $wgPageAttachment_useInternalCache; global $wgPageAttachment_internalCacheType; if (isset($wgPageAttachment_useInternalCache) && $wgPageAttachment_useInternalCache == true) { if (isset($wgPageAttachment_internalCacheType)) { if ($wgPageAttachment_internalCacheType == 'SQLite3') { $this->cache = new Provider\SQLiteCache(); } else { if ($wgPageAttachment_internalCacheType == 'Database') { $this->cache = new Provider\DatabaseCache(); } else { print '<br/>*** ERROR ***************************************************************<br/>'; print 'PageAttachment internal cache is enabled.<br/>'; print 'However, invalid PageAttachment internal cache type specified: ' . $wgPageAttachment_internalCacheType . '<br/>'; print '*************************************************************************<br/>'; } } } else { print '<br/>*** ERROR ***************************************************************<br/>'; print 'PageAttachment internal cache is enabled.<br/>'; print 'However, PageAttachment internal cache type is not specified.<br/>'; print '*************************************************************************<br/>'; } } else { $mwCacheObj = \wfGetMainCache(); $this->cache = new Provider\MWCacheObjWrapper($mwCacheObj); } } return $this->cache; }
/** * @params include: * - objectCache : Name of an object cache registered in $wgObjectCaches. * This defaults to the one specified by $wgMainCacheType. * - cacheTTL : Seconds to cache the aggregate data before regenerating. * @param array $params */ protected function __construct(array $params) { parent::__construct($params); $this->cache = isset($params['objectCache']) ? wfGetCache($params['objectCache']) : wfGetMainCache(); $this->cacheTTL = isset($params['cacheTTL']) ? $params['cacheTTL'] : 180; // 3 min }
public function __construct($parent) { global $wgMemc; $this->parent = $parent; $this->srvCache = ObjectCache::newAccelerator(array(), 'hash'); $this->mainCache = $wgMemc ?: wfGetMainCache(); }
/** * Construct a new instance from configuration. * * $config paramaters include: * 'dbServers' : Associative array of DB names to server configuration. * Configuration is an associative array that includes: * 'host' - DB server name * 'dbname' - DB name * 'type' - DB type (mysql,postgres,...) * 'user' - DB user * 'password' - DB user password * 'tablePrefix' - DB table prefix * 'flags' - DB flags (see DatabaseBase) * 'dbsByBucket' : Array of 1-16 consecutive integer keys, starting from 0, * each having an odd-numbered list of DB names (peers) as values. * Any DB named 'localDBMaster' will automatically use the DB master * settings for this wiki (without the need for a dbServers entry). * 'lockExpiry' : Lock timeout (seconds) for dropped connections. [optional] * This tells the DB server how long to wait before assuming * connection failure and releasing all the locks for a session. * * @param Array $config */ public function __construct(array $config) { $this->dbServers = isset($config['dbServers']) ? $config['dbServers'] : array(); // likely just using 'localDBMaster' // Sanitize dbsByBucket config to prevent PHP errors $this->dbsByBucket = array_filter($config['dbsByBucket'], 'is_array'); $this->dbsByBucket = array_values($this->dbsByBucket); // consecutive if (isset($config['lockExpiry'])) { $this->lockExpiry = $config['lockExpiry']; } else { $met = ini_get('max_execution_time'); $this->lockExpiry = $met ? $met : 60; // use some sane amount if 0 } $this->safeDelay = $this->lockExpiry <= 0 ? 60 : $this->lockExpiry; // cover worst case foreach ($this->dbsByBucket as $bucket) { if (count($bucket) > 1) { // Tracks peers that couldn't be queried recently to avoid lengthy // connection timeouts. This is useless if each bucket has one peer. $this->statusCache = wfGetMainCache(); break; } } $this->session = ''; for ($i = 0; $i < 5; $i++) { $this->session .= mt_rand(0, 2147483647); } $this->session = wfBaseConvert(sha1($this->session), 16, 36, 31); }
function setUp() { global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgDeferredUpdateList, $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, $parserMemc, $wgThumbnailScriptPath, $wgScriptPath, $wgArticlePath, $wgStyleSheetPath, $wgScript, $wgStylePath; $wgScript = '/index.php'; $wgScriptPath = '/'; $wgArticlePath = '/wiki/$1'; $wgStyleSheetPath = '/skins'; $wgStylePath = '/skins'; $wgThumbnailScriptPath = false; $wgLocalFileRepo = array('class' => 'LocalRepo', 'name' => 'local', 'directory' => wfTempDir() . '/test-repo', 'url' => 'http://example.com/images', 'deletedDir' => wfTempDir() . '/test-repo/delete', 'hashLevels' => 2, 'transformVia404' => false); $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; $wgEnableParserCache = false; $wgDeferredUpdateList = array(); $wgMemc = wfGetMainCache(); $messageMemc = wfGetMessageCacheStorage(); $parserMemc = wfGetParserCacheStorage(); // $wgContLang = new StubContLang; $wgUser = new User(); $context = new RequestContext(); $wgLang = $context->getLang(); $wgOut = $context->getOutput(); $wgParser = new StubObject('wgParser', $wgParserConf['class'], array($wgParserConf)); $wgRequest = new WebRequest(); if ($wgStyleDirectory === false) { $wgStyleDirectory = "{$IP}/skins"; } }
/** * @since 1.21 * @deprecated 1.25 Construct a SiteStore instance directly instead. * * @param ORMTable|null $sitesTable * @param BagOStuff|null $cache * * @return SiteStore */ public static function newInstance(ORMTable $sitesTable = null, BagOStuff $cache = null) { if ($cache === null) { $cache = wfGetMainCache(); } $siteStore = new DBSiteStore(); return new static($siteStore, $cache); }
/** * Initialization */ private static function init() { clearstatcache(); self::$cache =& wfGetMainCache(); if (self::$cache instanceof FakeMemCachedClient) { self::$realCache = false; } }
public function execute() { $force = $this->getOption('force', false); $this->source = $this->getOption('source', 'https://en.wikipedia.org/w/api.php'); $this->cache = wfGetMainCache(); $data = $this->fetchLinks(); if ($data === false) { $this->error("Error during fetching data."); } else { $this->doPopulate($data, $force); } }
function setUp() { global $wgContLang, $wgNamespaceProtection, $wgNamespaceAliases; global $wgHooks, $IP; $wgContLang = Language::factory('en'); //Setup CLI arguments if ($this->getCliArg('regex=')) { $this->regex = $this->getCliArg('regex='); } else { # Matches anything $this->regex = ''; } $this->keepUploads = $this->getCliArg('keep-uploads'); $tmpGlobals = array(); $tmpGlobals['wgScript'] = '/index.php'; $tmpGlobals['wgScriptPath'] = '/'; $tmpGlobals['wgArticlePath'] = '/wiki/$1'; $tmpGlobals['wgStyleSheetPath'] = '/skins'; $tmpGlobals['wgStylePath'] = '/skins'; $tmpGlobals['wgThumbnailScriptPath'] = false; $tmpGlobals['wgLocalFileRepo'] = array('class' => 'LocalRepo', 'name' => 'local', 'url' => 'http://example.com/images', 'hashLevels' => 2, 'transformVia404' => false, 'backend' => 'local-backend'); $tmpGlobals['wgForeignFileRepos'] = array(); $tmpGlobals['wgEnableParserCache'] = false; $tmpGlobals['wgHooks'] = $wgHooks; $tmpGlobals['wgDeferredUpdateList'] = array(); $tmpGlobals['wgMemc'] = wfGetMainCache(); $tmpGlobals['messageMemc'] = wfGetMessageCacheStorage(); $tmpGlobals['parserMemc'] = wfGetParserCacheStorage(); // $tmpGlobals['wgContLang'] = new StubContLang; $tmpGlobals['wgUser'] = new User(); $context = new RequestContext(); $tmpGlobals['wgLang'] = $context->getLanguage(); $tmpGlobals['wgOut'] = $context->getOutput(); $tmpGlobals['wgParser'] = new StubObject('wgParser', $GLOBALS['wgParserConf']['class'], array($GLOBALS['wgParserConf'])); $tmpGlobals['wgRequest'] = $context->getRequest(); if ($GLOBALS['wgStyleDirectory'] === false) { $tmpGlobals['wgStyleDirectory'] = "{$IP}/skins"; } foreach ($tmpGlobals as $var => $val) { if (array_key_exists($var, $GLOBALS)) { $this->savedInitialGlobals[$var] = $GLOBALS[$var]; } $GLOBALS[$var] = $val; } $this->savedWeirdGlobals['mw_namespace_protection'] = $wgNamespaceProtection[NS_MEDIAWIKI]; $this->savedWeirdGlobals['image_alias'] = $wgNamespaceAliases['Image']; $this->savedWeirdGlobals['image_talk_alias'] = $wgNamespaceAliases['Image_talk']; $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; }
function getLagTimes($serverIndexes, $wiki) { wfProfileIn(__METHOD__); $expiry = 5; $requestRate = 10; global $wgMemc; if (empty($wgMemc)) { $wgMemc = wfGetMainCache(); } $masterName = $this->parent->getServerName(0); $memcKey = wfMemcKey('lag_times', $masterName); $times = $wgMemc->get($memcKey); if ($times) { # Randomly recache with probability rising over $expiry $elapsed = time() - $times['timestamp']; $chance = max(0, ($expiry - $elapsed) * $requestRate); if (mt_rand(0, $chance) != 0) { unset($times['timestamp']); wfProfileOut(__METHOD__); return $times; } wfIncrStats('lag_cache_miss_expired'); } else { wfIncrStats('lag_cache_miss_absent'); } # Cache key missing or expired $times = array(); foreach ($serverIndexes as $i) { if ($i == 0) { # Master $times[$i] = 0; } elseif (false !== ($conn = $this->parent->getAnyOpenConnection($i))) { $times[$i] = $conn->getLag(); } elseif (false !== ($conn = $this->parent->openConnection($i, $wiki))) { $times[$i] = $conn->getLag(); } } # Add a timestamp key so we know when it was cached $times['timestamp'] = time(); $wgMemc->set($memcKey, $times, $expiry); # But don't give the timestamp to the caller unset($times['timestamp']); $lagTimes = $times; wfProfileOut(__METHOD__); return $lagTimes; }
public static function suite() { $suite = new PHPUnit_Framework_TestSuite(); self::$iter = new TestFileIterator(PARSER_TESTS); foreach (self::$iter as $i => $test) { $suite->addTest(new ParserUnitTest($i, $test['test'])); self::$count++; } unset($tests); self::$parser = new PTShell(); self::$iter->setParser(self::$parser); self::$parser->recorder->start(); self::$parser->setupDatabase(); self::$iter->rewind(); /* } */ /* function setUp() { */ global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgDeferredUpdateList, $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, $wgMessageCache, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $parserMemc, $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, $wgNamespacesWithSubpages, $wgThumbnailScriptPath, $wgScriptPath, $wgArticlePath, $wgStyleSheetPath, $wgScript, $wgStylePath; $wgScript = '/index.php'; $wgScriptPath = '/'; $wgArticlePath = '/wiki/$1'; $wgStyleSheetPath = '/skins'; $wgStylePath = '/skins'; $wgThumbnailScriptPath = false; $wgLocalFileRepo = array('class' => 'LocalRepo', 'name' => 'local', 'directory' => '', 'url' => 'http://example.com/images', 'hashLevels' => 2, 'transformVia404' => false); $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; $wgEnableParserCache = false; $wgDeferredUpdateList = array(); $wgMemc =& wfGetMainCache(); $messageMemc =& wfGetMessageCacheStorage(); $parserMemc =& wfGetParserCacheStorage(); $wgContLang = new StubContLang(); $wgUser = new StubUser(); $wgLang = new StubUserLang(); $wgOut = new StubObject('wgOut', 'OutputPage'); $wgParser = new StubObject('wgParser', $wgParserConf['class'], array($wgParserConf)); $wgRequest = new WebRequest(); $wgMessageCache = new StubObject('wgMessageCache', 'MessageCache', array($messageMemc, $wgUseDatabaseMessages, $wgMsgCacheExpiry, wfWikiID())); if ($wgStyleDirectory === false) { $wgStyleDirectory = "{$IP}/skins"; } return $suite; }
protected function setUp() { global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgParserCacheType, $wgNamespaceAliases, $wgNamespaceProtection, $parserMemc; $tmpDir = $this->getNewTempDirectory(); $tmpGlobals = []; $tmpGlobals['wgScript'] = '/index.php'; $tmpGlobals['wgScriptPath'] = '/'; $tmpGlobals['wgArticlePath'] = '/wiki/$1'; $tmpGlobals['wgStylePath'] = '/skins'; $tmpGlobals['wgThumbnailScriptPath'] = false; $tmpGlobals['wgLocalFileRepo'] = ['class' => 'LocalRepo', 'name' => 'local', 'url' => 'http://example.com/images', 'hashLevels' => 2, 'transformVia404' => false, 'backend' => new FSFileBackend(['name' => 'local-backend', 'wikiId' => wfWikiID(), 'containerPaths' => ['local-public' => "{$tmpDir}/test-repo/public", 'local-thumb' => "{$tmpDir}/test-repo/thumb", 'local-temp' => "{$tmpDir}/test-repo/temp", 'local-deleted' => "{$tmpDir}/test-repo/delete"]])]; foreach ($tmpGlobals as $var => $val) { if (array_key_exists($var, $GLOBALS)) { $this->savedGlobals[$var] = $GLOBALS[$var]; } $GLOBALS[$var] = $val; } $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; $wgParserCacheType = CACHE_NONE; DeferredUpdates::clearPendingUpdates(); $wgMemc = wfGetMainCache(); $messageMemc = wfGetMessageCacheStorage(); $parserMemc = wfGetParserCacheStorage(); RequestContext::resetMain(); $context = RequestContext::getMain(); $wgUser = new User(); $wgLang = $context->getLanguage(); $wgOut = $context->getOutput(); $wgParser = new StubObject('wgParser', $wgParserConf['class'], [$wgParserConf]); $wgRequest = $context->getRequest(); if ($wgStyleDirectory === false) { $wgStyleDirectory = "{$IP}/skins"; } RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); }
public function __construct() { global $IP; // No Setup.php yet. Initialise everything by ourselves require_once $IP . '/includes/GlobalFunctions.php'; require_once $IP . '/includes/ObjectCache.php'; $wgMemc = wfGetMainCache(); // Caching not yet working $cached = false; //$wgMemc->get( 'configurewmf:data' ); if ($cached) { $this->overrides = $cached; return; } $dbr = self::getSlaveDB(); $r = $dbr->select('config_overrides', array('cfg_target', 'cfg_value'), null, __METHOD__); $overrides = array(); while ($row = $dbr->fetchObject($r)) { $overrides[] = array('target' => $row->cfg_target, 'value' => unserialize($row->cfg_value)); } $wgMemc->set('configurewmf:data', $overrides); $this->overrides = $overrides; }
/** * @see FileBackendStore::__construct() * Additional $config params include: * swiftAuthUrl : Swift authentication server URL * swiftUser : Swift user used by MediaWiki (account:username) * swiftKey : Swift authentication key for the above user * swiftAuthTTL : Swift authentication TTL (seconds) * swiftAnonUser : Swift user used for end-user requests (account:username) * shardViaHashLevels : Map of container names to sharding config with: * 'base' : base of hash characters, 16 or 36 * 'levels' : the number of hash levels (and digits) * 'repeat' : hash subdirectories are prefixed with all the * parent hash directory names (e.g. "a/ab/abc") * swiftTimeout : number of seconds timeout consistent with php-cloudfiles. Default: 10 */ public function __construct(array $config) { parent::__construct($config); // Required settings $this->auth = new CF_Authentication($config['swiftUser'], $config['swiftKey'], null, $config['swiftAuthUrl']); /* <Wikia> */ if (!empty($config['debug'])) { $this->auth->setDebug($config['debug']); } $this->swiftTimeout = isset($config['swiftTimeout']) ? intval($config['swiftTimeout']) : 10; /* </Wikia> */ // Optional settings $this->authTTL = isset($config['swiftAuthTTL']) ? $config['swiftAuthTTL'] : 120; // some sane number $this->swiftAnonUser = isset($config['swiftAnonUser']) ? $config['swiftAnonUser'] : ''; $this->shardViaHashLevels = isset($config['shardViaHashLevels']) ? $config['shardViaHashLevels'] : ''; /* <Wikia> */ // caching credentials if (!empty($config['cacheAuthInfo']) && $config['cacheAuthInfo'] === true) { $this->srvCache = wfGetMainCache(); } $this->srvCache = $this->srvCache ? $this->srvCache : new EmptyBagOStuff(); /* </Wikia> */ }
/** * Purges the internal and external cache of the site list, forcing the list * of sites to be re-read from the database. * * @since 1.21 */ public function reset() { wfProfileIn(__METHOD__); // purge cache $cache = wfGetMainCache(); $cache->delete($this->getCacheKey()); $this->sites = null; wfProfileOut(__METHOD__); }
/** * Start a transaction and lock the image for update * Increments a reference counter if the lock is already held * @throws MWException * @return bool True if the image exists, false otherwise */ function lock() { $dbw = $this->repo->getMasterDB(); if (!$this->locked) { if (!$dbw->trxLevel()) { $dbw->begin(__METHOD__); $this->lockedOwnTrx = true; } $this->locked++; // Bug 54736: use simple lock to handle when the file does not exist. // SELECT FOR UPDATE only locks records not the gaps where there are none. $cache = wfGetMainCache(); $key = $this->getCacheKey(); if (!$cache->lock($key, 5)) { throw new MWException("Could not acquire lock for '{$this->getName()}.'"); } $dbw->onTransactionIdle(function () use($cache, $key) { $cache->unlock($key); // release on commit }); } return $dbw->selectField('image', '1', array('img_name' => $this->getName()), __METHOD__, array('FOR UPDATE')); }
// Useful debug output if ($wgCommandLineMode) { wfDebug("\n\nStart command line script {$self}\n"); } else { $debug = "\n\nStart request {$wgRequest->getMethod()} {$wgRequest->getRequestURL()}\n"; if ($wgDebugPrintHttpHeaders) { $debug .= "HTTP HEADERS:\n"; foreach ($wgRequest->getAllHeaders() as $name => $value) { $debug .= "{$name}: {$value}\n"; } } wfDebug($debug); } Profiler::instance()->scopedProfileOut($ps_misc); $ps_memcached = Profiler::instance()->scopedProfileIn($fname . '-memcached'); $wgMemc = wfGetMainCache(); $messageMemc = wfGetMessageCacheStorage(); $parserMemc = wfGetParserCacheStorage(); wfDebugLog('caches', 'cluster: ' . get_class($wgMemc) . ', WAN: ' . ($wgMainWANCache === CACHE_NONE ? 'CACHE_NONE' : $wgMainWANCache) . ', stash: ' . $wgMainStash . ', message: ' . get_class($messageMemc) . ', parser: ' . get_class($parserMemc) . ', session: ' . get_class(ObjectCache::getInstance($wgSessionCacheType))); Profiler::instance()->scopedProfileOut($ps_memcached); // Most of the config is out, some might want to run hooks here. Hooks::run('SetupAfterCache'); $ps_globals = Profiler::instance()->scopedProfileIn($fname . '-globals'); /** * @var Language $wgContLang */ $wgContLang = Language::factory($wgLanguageCode); $wgContLang->initContLang(); // Now that variant lists may be available... $wgRequest->interpolateTitle(); if (!is_object($wgAuth)) {
/** * Highlight a code-block using a particular lexer. * * @param string $code Code to highlight. * @param string|null $lang Language name, or null to use plain markup. * @param array $args Associative array of additional arguments. * If it contains a 'line' key, the output will include line numbers. * If it includes a 'highlight' key, the value will be parsed as a * comma-separated list of lines and line-ranges to highlight. * If it contains a 'start' key, the value will be used as the line at which to * start highlighting. * If it contains a 'inline' key, the output will not be wrapped in `<div><pre/></div>`. * @return Status Status object, with HTML representing the highlighted * code as its value. */ protected static function highlight($code, $lang = null, $args = array()) { global $wgPygmentizePath; $status = new Status(); $lexer = self::getLexer($lang); if ($lexer === null && $lang !== null) { $status->warning('syntaxhighlight-error-unknown-language', $lang); } $length = strlen($code); if (strlen($code) > self::HIGHLIGHT_MAX_BYTES) { $status->warning('syntaxhighlight-error-exceeds-size-limit', $length, self::HIGHLIGHT_MAX_BYTES); $lexer = null; } if (wfShellExecDisabled() !== false) { $status->warning('syntaxhighlight-error-pygments-invocation-failure'); wfWarn('MediaWiki determined that it cannot invoke Pygments. ' . 'As a result, SyntaxHighlight_GeSHi will not perform any syntax highlighting. ' . 'See the debug log for details: ' . 'https://www.mediawiki.org/wiki/Manual:$wgDebugLogFile'); $lexer = null; } $inline = isset($args['inline']); if ($lexer === null) { if ($inline) { $status->value = htmlspecialchars(trim($code), ENT_NOQUOTES); } else { $pre = Html::element('pre', array(), $code); $status->value = Html::rawElement('div', array('class' => self::HIGHLIGHT_CSS_CLASS), $pre); } return $status; } $options = array('cssclass' => self::HIGHLIGHT_CSS_CLASS, 'encoding' => 'utf-8'); // Line numbers if (isset($args['line'])) { $options['linenos'] = 'inline'; } if ($lexer === 'php' && strpos($code, '<?php') === false) { $options['startinline'] = 1; } // Highlight specific lines if (isset($args['highlight'])) { $lines = self::parseHighlightLines($args['highlight']); if (count($lines)) { $options['hl_lines'] = implode(' ', $lines); } } // Starting line number if (isset($args['start'])) { $options['linenostart'] = $args['start']; } if ($inline) { $options['nowrap'] = 1; } $cache = wfGetMainCache(); $cacheKey = self::makeCacheKey($code, $lexer, $options); $output = $cache->get($cacheKey); if ($output === false) { $optionPairs = array(); foreach ($options as $k => $v) { $optionPairs[] = "{$k}={$v}"; } $builder = new ProcessBuilder(); $builder->setPrefix($wgPygmentizePath); $process = $builder->add('-l')->add($lexer)->add('-f')->add('html')->add('-O')->add(implode(',', $optionPairs))->getProcess(); $process->setInput($code); $process->run(); if (!$process->isSuccessful()) { $status->warning('syntaxhighlight-error-pygments-invocation-failure'); wfWarn('Failed to invoke Pygments: ' . $process->getErrorOutput()); $status->value = self::highlight($code, null, $args)->getValue(); return $status; } $output = $process->getOutput(); $cache->set($cacheKey, $output); } if ($inline) { $output = trim($output); } $status->value = $output; return $status; }
/** * @params include: * - sectionsByWiki : A map of wiki IDs to section names. * Wikis will default to using the section "default". * - partitionsBySection : Map of section names to maps of (partition name => weight). * A section called 'default' must be defined if not all wikis * have explicitly defined sections. * - configByPartition : Map of queue partition names to configuration arrays. * These configuration arrays are passed to JobQueue::factory(). * The options set here are overriden by those passed to this * the federated queue itself (e.g. 'order' and 'claimTTL'). * - partitionsNoPush : List of partition names that can handle pop() but not push(). * This can be used to migrate away from a certain partition. * @param array $params */ protected function __construct( array $params ) { parent::__construct( $params ); $section = isset( $params['sectionsByWiki'][$this->wiki] ) ? $params['sectionsByWiki'][$this->wiki] : 'default'; if ( !isset( $params['partitionsBySection'][$section] ) ) { throw new MWException( "No configuration for section '$section'." ); } // Get the full partition map $this->partitionMap = $params['partitionsBySection'][$section]; arsort( $this->partitionMap, SORT_NUMERIC ); // Get the partitions jobs can actually be pushed to $partitionPushMap = $this->partitionMap; if ( isset( $params['partitionsNoPush'] ) ) { foreach ( $params['partitionsNoPush'] as $partition ) { unset( $partitionPushMap[$partition] ); } } // Get the config to pass to merge into each partition queue config $baseConfig = $params; foreach ( array( 'class', 'sectionsByWiki', 'partitionsBySection', 'configByPartition', 'partitionsNoPush' ) as $o ) { unset( $baseConfig[$o] ); } // Get the partition queue objects foreach ( $this->partitionMap as $partition => $w ) { if ( !isset( $params['configByPartition'][$partition] ) ) { throw new MWException( "No configuration for partition '$partition'." ); } $this->partitionQueues[$partition] = JobQueue::factory( $baseConfig + $params['configByPartition'][$partition] ); } // Get the ring of partitions to push jobs into $this->partitionPushRing = new HashRing( $partitionPushMap ); // Aggregate cache some per-queue values if there are multiple partition queues $this->cache = count( $this->partitionMap ) > 1 ? wfGetMainCache() : new EmptyBagOStuff(); }
/** * execute * * entry point for TaskExecutor * * @access public * @author eloy@wikia * * @param mixed $params default null - task data from wikia_tasks table * * @return boolean - status of operation */ public function execute($params = null) { global $IP, $wgWikiaLocalSettingsPath, $wgWikiaAdminSettingsPath, $wgExtensionMessagesFiles; $this->mTaskID = $params->task_id; $this->mParams = unserialize($params->task_arguments); $city_id = $this->mParams["city_id"]; $command = $this->mParams["command"]; $type = $this->mParams["type"]; $server = $this->mParams["server"]; $this->addLog("wgServer for this site is: {$server}"); if ($city_id && $command) { $this->mWikiId = $city_id; /** * execute maintenance script */ $cmd = sprintf("SERVER_ID={$city_id} php {$IP}/{$command} --server={$server} --conf {$wgWikiaLocalSettingsPath} --aconf {$wgWikiaAdminSettingsPath}"); $this->addLog("Running {$cmd}"); $retval = wfShellExec($cmd, $status); $this->addLog($retval); if ($type == "ACWLocal" || $type == "CWLocal") { $cmd = sprintf("SERVER_ID={$city_id} php {$IP}/maintenance/update.php --server={$server} --quick --nopurge --conf {$wgWikiaLocalSettingsPath} --aconf {$wgWikiaAdminSettingsPath}"); $this->addLog("Running {$cmd}"); $retval = wfShellExec($cmd, $status); $this->addLog($retval); $cmd = sprintf("SERVER_ID={$city_id} php {$IP}/maintenance/initStats.php --server={$server} --conf {$wgWikiaLocalSettingsPath} --aconf {$wgWikiaAdminSettingsPath}"); $this->addLog("Running {$cmd}"); $retval = wfShellExec($cmd, $status); $this->addLog($retval); $cmd = sprintf("SERVER_ID={$city_id} php {$IP}/maintenance/refreshLinks.php --server={$server} --new-only --conf {$wgWikiaLocalSettingsPath} --aconf {$wgWikiaAdminSettingsPath}"); $this->addLog("Running {$cmd}"); $retval = wfShellExec($cmd, $status); $this->addLog($retval); $this->addLog("Remove edit lock"); $oVariable = WikiFactory::getVarByName('wgReadOnly', $city_id); if (isset($oVariable->cv_variable_id)) { WikiFactory::removeVarById($oVariable->cv_variable_id, $city_id); WikiFactory::clearCache($city_id); } } $dbname = WikiFactory::IDtoDB($city_id); $cmd = sprintf("perl /usr/wikia/backend/bin/scribe/events_local_users.pl --usedb={$dbname} "); $this->addLog("Running {$cmd}"); $retval = wfShellExec($cmd, $status); $this->addLog($retval); /** * once again clear cache at the very end */ $wgMemc = wfGetMainCache(); $wgMemc->delete(WikiFactory::getVarsKey($city_id)); } return true; }
/** * @see FileBackendStore::__construct() * Additional $config params include: * - swiftAuthUrl : Swift authentication server URL * - swiftUser : Swift user used by MediaWiki (account:username) * - swiftKey : Swift authentication key for the above user * - swiftAuthTTL : Swift authentication TTL (seconds) * - swiftTempUrlKey : Swift "X-Account-Meta-Temp-URL-Key" value on the account. * Do not set this until it has been set in the backend. * - shardViaHashLevels : Map of container names to sharding config with: * - base : base of hash characters, 16 or 36 * - levels : the number of hash levels (and digits) * - repeat : hash subdirectories are prefixed with all the * parent hash directory names (e.g. "a/ab/abc") * - cacheAuthInfo : Whether to cache authentication tokens in APC, XCache, ect. * If those are not available, then the main cache will be used. * This is probably insecure in shared hosting environments. * - rgwS3AccessKey : Rados Gateway S3 "access key" value on the account. * Do not set this until it has been set in the backend. * This is used for generating expiring pre-authenticated URLs. * Only use this when using rgw and to work around * http://tracker.newdream.net/issues/3454. * - rgwS3SecretKey : Rados Gateway S3 "secret key" value on the account. * Do not set this until it has been set in the backend. * This is used for generating expiring pre-authenticated URLs. * Only use this when using rgw and to work around * http://tracker.newdream.net/issues/3454. */ public function __construct(array $config) { parent::__construct($config); // Required settings $this->swiftAuthUrl = $config['swiftAuthUrl']; $this->swiftUser = $config['swiftUser']; $this->swiftKey = $config['swiftKey']; // Optional settings $this->authTTL = isset($config['swiftAuthTTL']) ? $config['swiftAuthTTL'] : 15 * 60; // some sane number $this->swiftTempUrlKey = isset($config['swiftTempUrlKey']) ? $config['swiftTempUrlKey'] : ''; $this->shardViaHashLevels = isset($config['shardViaHashLevels']) ? $config['shardViaHashLevels'] : ''; $this->rgwS3AccessKey = isset($config['rgwS3AccessKey']) ? $config['rgwS3AccessKey'] : ''; $this->rgwS3SecretKey = isset($config['rgwS3SecretKey']) ? $config['rgwS3SecretKey'] : ''; // HTTP helper client $this->http = new MultiHttpClient(array()); // Cache container information to mask latency if (isset($config['wanCache']) && $config['wanCache'] instanceof WANObjectCache) { $this->memCache = $config['wanCache']; } // Process cache for container info $this->containerStatCache = new ProcessCacheLRU(300); // Cache auth token information to avoid RTTs if (!empty($config['cacheAuthInfo'])) { if (PHP_SAPI === 'cli') { $this->srvCache = wfGetMainCache(); // preferrably memcached } else { try { // look for APC, XCache, WinCache, ect... $this->srvCache = ObjectCache::newAccelerator(array()); } catch (Exception $e) { } } } $this->srvCache = $this->srvCache ?: new EmptyBagOStuff(); }
public function tearDown() { // Don't screw anyone else F::app()->wg->Memc = wfGetMainCache(); }
/** * @see FileBackendStore::__construct() * Additional $config params include: * - swiftAuthUrl : Swift authentication server URL * - swiftUser : Swift user used by MediaWiki (account:username) * - swiftKey : Swift authentication key for the above user * - swiftAuthTTL : Swift authentication TTL (seconds) * - swiftTempUrlKey : Swift "X-Account-Meta-Temp-URL-Key" value on the account. * Do not set this until it has been set in the backend. * - swiftAnonUser : Swift user used for end-user requests (account:username). * If set, then views of public containers are assumed to go * through this user. If not set, then public containers are * accessible to unauthenticated requests via ".r:*" in the ACL. * - swiftUseCDN : Whether a Cloud Files Content Delivery Network is set up * - swiftCDNExpiry : How long (in seconds) to store content in the CDN. * If files may likely change, this should probably not exceed * a few days. For example, deletions may take this long to apply. * If object purging is enabled, however, this is not an issue. * - swiftCDNPurgable : Whether object purge requests are allowed by the CDN. * - shardViaHashLevels : Map of container names to sharding config with: * - base : base of hash characters, 16 or 36 * - levels : the number of hash levels (and digits) * - repeat : hash subdirectories are prefixed with all the * parent hash directory names (e.g. "a/ab/abc") * - cacheAuthInfo : Whether to cache authentication tokens in APC, XCache, ect. * If those are not available, then the main cache will be used. * This is probably insecure in shared hosting environments. * - rgwS3AccessKey : Ragos Gateway S3 "access key" value on the account. * Do not set this until it has been set in the backend. * This is used for generating expiring pre-authenticated URLs. * Only use this when using rgw and to work around * http://tracker.newdream.net/issues/3454. * - rgwS3SecretKey : Ragos Gateway S3 "secret key" value on the account. * Do not set this until it has been set in the backend. * This is used for generating expiring pre-authenticated URLs. * Only use this when using rgw and to work around * http://tracker.newdream.net/issues/3454. */ public function __construct(array $config) { parent::__construct($config); if (!class_exists('CF_Constants')) { throw new MWException('SwiftCloudFiles extension not installed.'); } // Required settings $this->auth = new CF_Authentication($config['swiftUser'], $config['swiftKey'], null, $config['swiftAuthUrl']); // Optional settings $this->authTTL = isset($config['swiftAuthTTL']) ? $config['swiftAuthTTL'] : 5 * 60; // some sane number $this->swiftAnonUser = isset($config['swiftAnonUser']) ? $config['swiftAnonUser'] : ''; $this->swiftTempUrlKey = isset($config['swiftTempUrlKey']) ? $config['swiftTempUrlKey'] : ''; $this->shardViaHashLevels = isset($config['shardViaHashLevels']) ? $config['shardViaHashLevels'] : ''; $this->swiftUseCDN = isset($config['swiftUseCDN']) ? $config['swiftUseCDN'] : false; $this->swiftCDNExpiry = isset($config['swiftCDNExpiry']) ? $config['swiftCDNExpiry'] : 12 * 3600; // 12 hours is safe (tokens last 24 hours per http://docs.openstack.org) $this->swiftCDNPurgable = isset($config['swiftCDNPurgable']) ? $config['swiftCDNPurgable'] : true; $this->rgwS3AccessKey = isset($config['rgwS3AccessKey']) ? $config['rgwS3AccessKey'] : ''; $this->rgwS3SecretKey = isset($config['rgwS3SecretKey']) ? $config['rgwS3SecretKey'] : ''; // Cache container information to mask latency $this->memCache = wfGetMainCache(); // Process cache for container info $this->connContainerCache = new ProcessCacheLRU(300); // Cache auth token information to avoid RTTs if (!empty($config['cacheAuthInfo'])) { if (PHP_SAPI === 'cli') { $this->srvCache = wfGetMainCache(); // preferrably memcached } else { try { // look for APC, XCache, WinCache, ect... $this->srvCache = ObjectCache::newAccelerator(array()); } catch (Exception $e) { } } } $this->srvCache = $this->srvCache ? $this->srvCache : new EmptyBagOStuff(); }
/** * Return a singleton instance, based on the global configs. * @return HKDF */ protected static function singleton() { global $wgHKDFAlgorithm, $wgHKDFSecret, $wgSecretKey; $secret = $wgHKDFSecret ?: $wgSecretKey; if (!$secret) { throw new MWException("Cannot use MWCryptHKDF without a secret."); } // In HKDF, the context can be known to the attacker, but this will // keep simultaneous runs from producing the same output. $context = array(); $context[] = microtime(); $context[] = getmypid(); $context[] = gethostname(); // Setup salt cache. Use APC, or fallback to the main cache if it isn't setup try { $cache = ObjectCache::newAccelerator(array()); } catch (Exception $e) { $cache = wfGetMainCache(); } if (is_null(self::$singleton)) { self::$singleton = new self($secret, $wgHKDFAlgorithm, $cache, $context); } return self::$singleton; }
public function newFileFetcher() { return new CachingFileFetcher($this->gitHubFetcher === 'mediawiki' ? new MediaWikiFileFetcher() : new SimpleFileFetcher(), new CombinatoryCache(array(new SimpleInMemoryCache(), new MediaWikiCache(wfGetMainCache(), $this->cacheTime)))); }
/** * @covers CachingSiteStore::clear */ public function testClear() { $store = new CachingSiteStore(new HashSiteStore(), wfGetMainCache()); $this->assertTrue($store->clear()); $site = $store->getSite('enwiki'); $this->assertNull($site); $sites = $store->getSites(); $this->assertEquals(0, $sites->count()); }
public function maintenance($server) { global $wgCityId, $IP; $cmd = sprintf("SERVER_ID={$wgCityId} php {$IP}/maintenance/update.php --server={$server} --quick --nopurge"); $output = wfShellExec($cmd, $exitStatus); $this->info('run update.php', ['exitStatus' => $exitStatus, 'output' => $output]); $cmd = sprintf("SERVER_ID={$wgCityId} php {$IP}/maintenance/initStats.php --server={$server}"); $output = wfShellExec($cmd, $exitStatus); $this->info('run initStats.php', ['exitStatus' => $exitStatus, 'output' => $output]); $cmd = sprintf("SERVER_ID={$wgCityId} php {$IP}/maintenance/refreshLinks.php --server={$server} --new-only"); $output = wfShellExec($cmd, $exitStatus); $this->info('run refreshLinks.php', ['exitStatus' => $exitStatus, 'output' => $output]); $this->info("Remove edit lock"); $variable = \WikiFactory::getVarByName('wgReadOnly', $wgCityId); if (isset($variable->cv_variable_id)) { \WikiFactory::removeVarById($variable->cv_variable_id, $wgCityId); \WikiFactory::clearCache($wgCityId); } $dbname = \WikiFactory::IDtoDB($wgCityId); $founder = $this->founder->getId(); $cmd = sprintf("perl /usr/wikia/backend/bin/scribe/events_local_users.pl --usedb={$dbname} --user={$founder} "); $output = wfShellExec($cmd, $exitStatus); $this->info('run events_local_users.pl', ['exitStatus' => $exitStatus, 'output' => $output]); $wgMemc = wfGetMainCache(); $wgMemc->delete(\WikiFactory::getVarsKey($wgCityId)); return true; }
static function initCacheSupport() { self::$cache =& wfGetMainCache(); if (self::$cache instanceof FakeMemCachedClient) { self::$realCache = false; } }
/** * If patrol is possible, output a patrol UI box. This is called from the * footer section of ordinary page views. If patrol is not possible or not * desired, does nothing. * Side effect: When the patrol link is build, this method will call * OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax. * * @return bool */ public function showPatrolFooter() { global $wgUseNPPatrol, $wgUseRCPatrol, $wgEnableAPI, $wgEnableWriteAPI; $outputPage = $this->getContext()->getOutput(); $user = $this->getContext()->getUser(); $cache = wfGetMainCache(); $rc = false; if (!$this->getTitle()->quickUserCan('patrol', $user) || !($wgUseRCPatrol || $wgUseNPPatrol)) { // Patrolling is disabled or the user isn't allowed to return false; } // New page patrol: Get the timestamp of the oldest revison which // the revision table holds for the given page. Then we look // whether it's within the RC lifespan and if it is, we try // to get the recentchanges row belonging to that entry // (with rc_new = 1). if ($this->mRevision && !RecentChange::isInRCLifespan($this->mRevision->getTimestamp(), 21600)) { // The current revision is already older than what could be in the RC table // 6h tolerance because the RC might not be cleaned out regularly return false; } // Check for cached results $key = wfMemcKey('NotPatrollablePage', $this->getTitle()->getArticleID()); if ($cache->get($key)) { return false; } $dbr = wfGetDB(DB_SLAVE); $oldestRevisionTimestamp = $dbr->selectField('revision', 'MIN( rev_timestamp )', array('rev_page' => $this->getTitle()->getArticleID()), __METHOD__); if ($oldestRevisionTimestamp && RecentChange::isInRCLifespan($oldestRevisionTimestamp, 21600)) { // 6h tolerance because the RC might not be cleaned out regularly $rc = RecentChange::newFromConds(array('rc_new' => 1, 'rc_timestamp' => $oldestRevisionTimestamp, 'rc_namespace' => $this->getTitle()->getNamespace(), 'rc_cur_id' => $this->getTitle()->getArticleID()), __METHOD__, array('USE INDEX' => 'new_name_timestamp')); } else { // Cache the information we gathered above in case we can't patrol // Don't cache in case we can patrol as this could change $cache->set($key, '1'); } if (!$rc) { // Don't cache: This can be hit if the page gets accessed very fast after // its creation or in case we have high slave lag. In case the revision is // too old, we will already return above. return false; } if ($rc->getAttribute('rc_patrolled')) { // Patrolled RC entry around // Cache the information we gathered above in case we can't patrol // Don't cache in case we can patrol as this could change $cache->set($key, '1'); return false; } if ($rc->getPerformer()->equals($user)) { // Don't show a patrol link for own creations. If the user could // patrol them, they already would be patrolled return false; } $rcid = $rc->getAttribute('rc_id'); $token = $user->getEditToken($rcid); $outputPage->preventClickjacking(); if ($wgEnableAPI && $wgEnableWriteAPI && $user->isAllowed('writeapi')) { $outputPage->addModules('mediawiki.page.patrol.ajax'); } $link = Linker::linkKnown($this->getTitle(), wfMessage('markaspatrolledtext')->escaped(), array(), array('action' => 'markpatrolled', 'rcid' => $rcid, 'token' => $token)); $outputPage->addHTML("<div class='patrollink'>" . wfMessage('markaspatrolledlink')->rawParams($link)->escaped() . '</div>'); return true; }
public function getLagTimes($serverIndexes, $wiki) { if (count($serverIndexes) == 1 && reset($serverIndexes) == 0) { // Single server only, just return zero without caching return array(0 => 0); } $section = new ProfileSection(__METHOD__); $expiry = 5; $requestRate = 10; global $wgMemc; if (empty($wgMemc)) { $wgMemc = wfGetMainCache(); } $masterName = $this->parent->getServerName(0); $memcKey = wfMemcKey('lag_times', $masterName); $times = $wgMemc->get($memcKey); if (is_array($times)) { # Randomly recache with probability rising over $expiry $elapsed = time() - $times['timestamp']; $chance = max(0, ($expiry - $elapsed) * $requestRate); if (mt_rand(0, $chance) != 0) { unset($times['timestamp']); // hide from caller return $times; } wfIncrStats('lag_cache_miss_expired'); } else { wfIncrStats('lag_cache_miss_absent'); } # Cache key missing or expired if ($wgMemc->add("{$memcKey}:lock", 1, 10)) { # Let this process alone update the cache value $unlocker = new ScopedCallback(function () use($wgMemc, $memcKey) { $wgMemc->delete($memcKey); }); } elseif (is_array($times)) { # Could not acquire lock but an old cache exists, so use it unset($times['timestamp']); // hide from caller return $times; } $times = array(); foreach ($serverIndexes as $i) { if ($i == 0) { # Master $times[$i] = 0; } elseif (false !== ($conn = $this->parent->getAnyOpenConnection($i))) { $times[$i] = $conn->getLag(); } elseif (false !== ($conn = $this->parent->openConnection($i, $wiki))) { $times[$i] = $conn->getLag(); } } # Add a timestamp key so we know when it was cached $times['timestamp'] = time(); $wgMemc->set($memcKey, $times, $expiry + 10); unset($times['timestamp']); // hide from caller return $times; }