Example #1
0
 /**
  * @covers WANObjectCache::touchCheckKey()
  * @covers WANObjectCache::resetCheckKey()
  * @covers WANObjectCache::getCheckKeyTime()
  */
 public function testTouchKeys()
 {
     $key = wfRandomString();
     $priorTime = microtime(true);
     usleep(1);
     $t0 = $this->cache->getCheckKeyTime($key);
     $this->assertGreaterThanOrEqual($priorTime, $t0, 'Check key auto-created');
     $priorTime = microtime(true);
     usleep(1);
     $this->cache->touchCheckKey($key);
     $t1 = $this->cache->getCheckKeyTime($key);
     $this->assertGreaterThanOrEqual($priorTime, $t1, 'Check key created');
     $t2 = $this->cache->getCheckKeyTime($key);
     $this->assertEquals($t1, $t2, 'Check key time did not change');
     usleep(1);
     $this->cache->touchCheckKey($key);
     $t3 = $this->cache->getCheckKeyTime($key);
     $this->assertGreaterThan($t2, $t3, 'Check key time increased');
     $t4 = $this->cache->getCheckKeyTime($key);
     $this->assertEquals($t3, $t4, 'Check key time did not change');
     usleep(1);
     $this->cache->resetCheckKey($key);
     $t5 = $this->cache->getCheckKeyTime($key);
     $this->assertGreaterThan($t4, $t5, 'Check key time increased');
     $t6 = $this->cache->getCheckKeyTime($key);
     $this->assertEquals($t5, $t6, 'Check key time did not change');
 }
 /**
  * Invalidate cache keys for modules using this message key.
  * Called by MessageCache when a message has changed.
  *
  * @param string $key Message key
  */
 public function updateMessage($key)
 {
     $moduleNames = $this->getResourceLoader()->getModulesByMessage($key);
     foreach ($moduleNames as $moduleName) {
         // Uses a holdoff to account for database slave lag (for MessageCache)
         $this->wanCache->touchCheckKey($this->wanCache->makeKey(__CLASS__, $moduleName));
     }
 }
 /**
  * @covers WANObjectCache::set()
  */
 public function testWritePending()
 {
     $value = 1;
     $key = wfRandomString();
     $opts = ['pending' => true];
     $this->cache->set($key, $value, 30, $opts);
     $this->assertEquals(false, $this->cache->get($key), "Pending value not written.");
 }
Example #4
0
 /**
  * Clear all stored messages. Mainly used after a mass rebuild.
  */
 function clear()
 {
     $langs = Language::fetchLanguageNames(null, 'mw');
     foreach (array_keys($langs) as $code) {
         # Global and local caches
         $this->wanCache->touchCheckKey(wfMemcKey('messages', $code));
     }
     $this->mLoadedLanguages = array();
 }
Example #5
0
 /**
  * @dataProvider provideAdaptiveTTL
  * @covers WANObjectCache::adaptiveTTL()
  * @param float|int $ago
  * @param int $maxTTL
  * @param int $minTTL
  * @param float $factor
  * @param int $adaptiveTTL
  */
 public function testAdaptiveTTL($ago, $maxTTL, $minTTL, $factor, $adaptiveTTL)
 {
     $mtime = $ago ? time() - $ago : $ago;
     $margin = 5;
     $ttl = $this->cache->adaptiveTTL($mtime, $maxTTL, $minTTL, $factor);
     $this->assertGreaterThanOrEqual($adaptiveTTL - $margin, $ttl);
     $this->assertLessThanOrEqual($adaptiveTTL + $margin, $ttl);
     $ttl = $this->cache->adaptiveTTL((string) $mtime, $maxTTL, $minTTL, $factor);
     $this->assertGreaterThanOrEqual($adaptiveTTL - $margin, $ttl);
     $this->assertLessThanOrEqual($adaptiveTTL + $margin, $ttl);
 }
Example #6
0
 /**
  * Do a batch lookup from cache for file stats for all paths
  * used in a list of storage paths or FileOp objects.
  * This loads the persistent cache values into the process cache.
  *
  * @param array $items List of storage paths
  */
 protected final function primeFileCache(array $items)
 {
     $ps = $this->scopedProfileSection(__METHOD__ . "-{$this->name}");
     $paths = [];
     // list of storage paths
     $pathNames = [];
     // (cache key => storage path)
     // Get all the paths/containers from the items...
     foreach ($items as $item) {
         if (self::isStoragePath($item)) {
             $paths[] = FileBackend::normalizeStoragePath($item);
         }
     }
     // Get rid of any paths that failed normalization...
     $paths = array_filter($paths, 'strlen');
     // remove nulls
     // Get all the corresponding cache keys for paths...
     foreach ($paths as $path) {
         list(, $rel, ) = $this->resolveStoragePath($path);
         if ($rel !== null) {
             // valid path for this backend
             $pathNames[$this->fileCacheKey($path)] = $path;
         }
     }
     // Get all cache entries for these file cache keys...
     $values = $this->memCache->getMulti(array_keys($pathNames));
     foreach ($values as $cacheKey => $val) {
         $path = $pathNames[$cacheKey];
         if (is_array($val)) {
             $val['latest'] = false;
             // never completely trust cache
             $this->cheapCache->set($path, 'stat', $val);
             if (isset($val['sha1'])) {
                 // some backends store SHA-1 as metadata
                 $this->cheapCache->set($path, 'sha1', ['hash' => $val['sha1'], 'latest' => false]);
             }
             if (isset($val['xattr'])) {
                 // some backends store headers/metadata
                 $val['xattr'] = self::normalizeXAttributes($val['xattr']);
                 $this->cheapCache->set($path, 'xattr', ['map' => $val['xattr'], 'latest' => false]);
             }
         }
     }
 }
Example #7
0
 public function __construct(array $conf)
 {
     $this->localDomain = isset($conf['localDomain']) ? DatabaseDomain::newFromId($conf['localDomain']) : DatabaseDomain::newUnspecified();
     if (isset($conf['readOnlyReason']) && is_string($conf['readOnlyReason'])) {
         $this->readOnlyReason = $conf['readOnlyReason'];
     }
     $this->srvCache = isset($conf['srvCache']) ? $conf['srvCache'] : new EmptyBagOStuff();
     $this->memCache = isset($conf['memCache']) ? $conf['memCache'] : new EmptyBagOStuff();
     $this->wanCache = isset($conf['wanCache']) ? $conf['wanCache'] : WANObjectCache::newEmpty();
     foreach (self::$loggerFields as $key) {
         $this->{$key} = isset($conf[$key]) ? $conf[$key] : new \Psr\Log\NullLogger();
     }
     $this->errorLogger = isset($conf['errorLogger']) ? $conf['errorLogger'] : function (Exception $e) {
         trigger_error(E_USER_WARNING, get_class($e) . ': ' . $e->getMessage());
     };
     $this->profiler = isset($params['profiler']) ? $params['profiler'] : null;
     $this->trxProfiler = isset($conf['trxProfiler']) ? $conf['trxProfiler'] : new TransactionProfiler();
     $this->requestInfo = ['IPAddress' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '', 'UserAgent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '', 'ChronologyProtection' => 'true'];
     $this->cliMode = isset($params['cliMode']) ? $params['cliMode'] : PHP_SAPI === 'cli';
     $this->hostname = isset($conf['hostname']) ? $conf['hostname'] : gethostname();
     $this->agent = isset($params['agent']) ? $params['agent'] : '';
     $this->ticket = mt_rand();
 }
Example #8
0
 /**
  * @return void
  */
 protected function doFlushCaches()
 {
     foreach (array('size', 'acquiredcount') as $type) {
         $this->cache->delete($this->getCacheKey($type));
     }
 }
Example #9
0
 /**
  * @since 1.27
  * @param WANObjectCache $cache
  * @return string
  */
 protected function getCacheKey(WANObjectCache $cache)
 {
     return $cache->makeGlobalKey('user', 'id', wfWikiID(), $this->mId);
 }
Example #10
0
 public function __construct(array $params)
 {
     if (!isset($params['servers'])) {
         throw new InvalidArgumentException(__CLASS__ . ': missing servers parameter');
     }
     $this->mServers = $params['servers'];
     $this->localDomain = isset($params['localDomain']) ? DatabaseDomain::newFromId($params['localDomain']) : DatabaseDomain::newUnspecified();
     // In case a caller assumes that the domain ID is simply <db>-<prefix>, which is almost
     // always true, gracefully handle the case when they fail to account for escaping.
     if ($this->localDomain->getTablePrefix() != '') {
         $this->localDomainIdAlias = $this->localDomain->getDatabase() . '-' . $this->localDomain->getTablePrefix();
     } else {
         $this->localDomainIdAlias = $this->localDomain->getDatabase();
     }
     $this->mWaitTimeout = isset($params['waitTimeout']) ? $params['waitTimeout'] : 10;
     $this->mReadIndex = -1;
     $this->mConns = ['local' => [], 'foreignUsed' => [], 'foreignFree' => []];
     $this->mLoads = [];
     $this->mWaitForPos = false;
     $this->mErrorConnection = false;
     $this->mAllowLagged = false;
     if (isset($params['readOnlyReason']) && is_string($params['readOnlyReason'])) {
         $this->readOnlyReason = $params['readOnlyReason'];
     }
     if (isset($params['loadMonitor'])) {
         $this->loadMonitorConfig = $params['loadMonitor'];
     } else {
         $this->loadMonitorConfig = ['class' => 'LoadMonitorNull'];
     }
     foreach ($params['servers'] as $i => $server) {
         $this->mLoads[$i] = $server['load'];
         if (isset($server['groupLoads'])) {
             foreach ($server['groupLoads'] as $group => $ratio) {
                 if (!isset($this->mGroupLoads[$group])) {
                     $this->mGroupLoads[$group] = [];
                 }
                 $this->mGroupLoads[$group][$i] = $ratio;
             }
         }
     }
     if (isset($params['srvCache'])) {
         $this->srvCache = $params['srvCache'];
     } else {
         $this->srvCache = new EmptyBagOStuff();
     }
     if (isset($params['memCache'])) {
         $this->memCache = $params['memCache'];
     } else {
         $this->memCache = new EmptyBagOStuff();
     }
     if (isset($params['wanCache'])) {
         $this->wanCache = $params['wanCache'];
     } else {
         $this->wanCache = WANObjectCache::newEmpty();
     }
     $this->profiler = isset($params['profiler']) ? $params['profiler'] : null;
     if (isset($params['trxProfiler'])) {
         $this->trxProfiler = $params['trxProfiler'];
     } else {
         $this->trxProfiler = new TransactionProfiler();
     }
     $this->errorLogger = isset($params['errorLogger']) ? $params['errorLogger'] : function (Exception $e) {
         trigger_error(get_class($e) . ': ' . $e->getMessage(), E_USER_WARNING);
     };
     foreach (['replLogger', 'connLogger', 'queryLogger', 'perfLogger'] as $key) {
         $this->{$key} = isset($params[$key]) ? $params[$key] : new \Psr\Log\NullLogger();
     }
     $this->host = isset($params['hostname']) ? $params['hostname'] : (gethostname() ?: 'unknown');
     $this->cliMode = isset($params['cliMode']) ? $params['cliMode'] : PHP_SAPI === 'cli';
     $this->agent = isset($params['agent']) ? $params['agent'] : '';
 }
 public function testArrayStorage()
 {
     $dewiki = ['iw_prefix' => 'de', 'iw_url' => 'http://de.wikipedia.org/wiki/', 'iw_local' => 1];
     $zzwiki = ['iw_prefix' => 'zz', 'iw_url' => 'http://zzwiki.org/wiki/', 'iw_local' => 0];
     $hash = $this->populateHash('en', [$dewiki], [$zzwiki]);
     $lookup = new \MediaWiki\Interwiki\ClassicInterwikiLookup(Language::factory('en'), WANObjectCache::newEmpty(), 60 * 60, $hash, 3, 'en');
     $this->assertEquals([$dewiki, $zzwiki], $lookup->getAllPrefixes(), 'getAllPrefixes()');
     $this->assertTrue($lookup->isValidInterwiki('de'), 'known prefix is valid');
     $this->assertTrue($lookup->isValidInterwiki('zz'), 'known prefix is valid');
     $interwiki = $lookup->fetch('de');
     $this->assertInstanceOf('Interwiki', $interwiki);
     $this->assertSame('http://de.wikipedia.org/wiki/', $interwiki->getURL(), 'getURL');
     $this->assertSame(true, $interwiki->isLocal(), 'isLocal');
     $interwiki = $lookup->fetch('zz');
     $this->assertInstanceOf('Interwiki', $interwiki);
     $this->assertSame('http://zzwiki.org/wiki/', $interwiki->getURL(), 'getURL');
     $this->assertSame(false, $interwiki->isLocal(), 'isLocal');
 }