Beispiel #1
0
 /**
  * @see FileBackend::getLocalReference()
  * @return TempFSFile|null
  */
 public function getLocalReference(array $params)
 {
     $path = self::normalizeStoragePath($params['src']);
     if ($path === null) {
         return null;
         // invalid storage path
     }
     wfProfileIn(__METHOD__);
     wfProfileIn(__METHOD__ . '-' . $this->name);
     $latest = !empty($params['latest']);
     // use latest data?
     if ($this->expensiveCache->has($path, 'localRef')) {
         $val = $this->expensiveCache->get($path, 'localRef');
         // If we want the latest data, check that this cached
         // value was in fact fetched with the latest available data.
         if (!$latest || $val['latest']) {
             wfProfileOut(__METHOD__ . '-' . $this->name);
             wfProfileOut(__METHOD__);
             return $val['object'];
         }
     }
     $tmpFile = $this->getLocalCopy($params);
     if ($tmpFile) {
         // don't cache negatives
         $this->expensiveCache->set($path, 'localRef', array('object' => $tmpFile, 'latest' => $latest));
     }
     wfProfileOut(__METHOD__ . '-' . $this->name);
     wfProfileOut(__METHOD__);
     return $tmpFile;
 }
 /**
  * Create a new BacklinkCache or reuse any existing one.
  * Currently, only one cache instance can exist; callers that
  * need multiple backlink cache objects should keep them in scope.
  *
  * @param Title $title : Title object to get a backlink cache for
  * @return BacklinkCache
  */
 public static function get(Title $title)
 {
     if (!self::$cache) {
         // init cache
         self::$cache = new ProcessCacheLRU(1);
     }
     $dbKey = $title->getPrefixedDBkey();
     if (!self::$cache->has($dbKey, 'obj')) {
         self::$cache->set($dbKey, 'obj', new self($title));
     }
     return self::$cache->get($dbKey, 'obj');
 }
Beispiel #3
0
	/**
	 * Check if jobs should not be popped of a queue right now.
	 * This is only used for performance, such as to avoid spamming
	 * the queue with many sub-jobs before they actually get run.
	 *
	 * @param $type string
	 * @return bool
	 */
	public function isQueueDeprioritized( $type ) {
		if ( $this->cache->has( 'isDeprioritized', $type, 5 ) ) {
			return $this->cache->get( 'isDeprioritized', $type );
		}
		if ( $type === 'refreshLinks2' ) {
			// Don't keep converting refreshLinks2 => refreshLinks jobs if the
			// later jobs have not been done yet. This helps throttle queue spam.
			$deprioritized = !$this->get( 'refreshLinks' )->isEmpty();
			$this->cache->set( 'isDeprioritized', $type, $deprioritized );
			return $deprioritized;
		}
		return false;
	}
 /**
  * Get lag time for each server
  *
  * Results are cached for a short time in memcached/process cache
  *
  * @param string|bool $wiki
  * @return int[] Map of (server index => seconds)
  */
 public function getLagTimes($wiki = false)
 {
     if ($this->getServerCount() <= 1) {
         return array(0 => 0);
         // no replication = no lag
     }
     if ($this->mProcCache->has('slave_lag', 'times', 1)) {
         return $this->mProcCache->get('slave_lag', 'times');
     }
     # Send the request to the load monitor
     $times = $this->getLoadMonitor()->getLagTimes(array_keys($this->mServers), $wiki);
     $this->mProcCache->set('slave_lag', 'times', $times);
     return $times;
 }
Beispiel #5
0
 /**
  * Search repositories for an image.
  * You can also use wfFindFile() to do this.
  *
  * @param Title|string $title Title object or string
  * @param array $options Associative array of options:
  *   time:           requested time for an archived image, or false for the
  *                   current version. An image object will be returned which was
  *                   created at the specified time.
  *   ignoreRedirect: If true, do not follow file redirects
  *   private:        If true, return restricted (deleted) files if the current
  *                   user is allowed to view them. Otherwise, such files will not
  *                   be found.
  *   latest:         If true, load from the latest available data into File objects
  * @return File|bool False if title is not found
  */
 function findFile($title, $options = [])
 {
     if (!is_array($options)) {
         // MW 1.15 compat
         $options = ['time' => $options];
     }
     if (isset($options['bypassCache'])) {
         $options['latest'] = $options['bypassCache'];
         // b/c
     }
     if (!$this->reposInitialised) {
         $this->initialiseRepos();
     }
     $title = File::normalizeTitle($title);
     if (!$title) {
         return false;
     }
     # Check the cache
     $dbkey = $title->getDBkey();
     if (empty($options['ignoreRedirect']) && empty($options['private']) && empty($options['bypassCache'])) {
         $time = isset($options['time']) ? $options['time'] : '';
         if ($this->cache->has($dbkey, $time, 60)) {
             return $this->cache->get($dbkey, $time);
         }
         $useCache = true;
     } else {
         $time = false;
         $useCache = false;
     }
     # Check the local repo
     $image = $this->localRepo->findFile($title, $options);
     # Check the foreign repos
     if (!$image) {
         foreach ($this->foreignRepos as $repo) {
             $image = $repo->findFile($title, $options);
             if ($image) {
                 break;
             }
         }
     }
     $image = $image ? $image : false;
     // type sanity
     # Cache file existence or non-existence
     if ($useCache && (!$image || $image->isCacheable())) {
         $this->cache->set($dbkey, $time, $image);
     }
     return $image;
 }
 /**
  * Translate legacy "title" paths to their "sha1" counterparts
  *
  * E.g. mwstore://local-backend/local-public/a/ab/<name>.jpg
  * => mwstore://local-backend/local-original/x/y/z/<sha1>.jpg
  *
  * @param array $paths
  * @param bool $latest
  * @return array Translated paths in same order
  */
 public function getBackendPaths(array $paths, $latest = true)
 {
     $db = $this->getDB($latest ? DB_MASTER : DB_SLAVE);
     $origBasePath = $this->backend->getContainerStoragePath("{$this->repoName}-original");
     // @TODO: batching
     $resolved = array();
     foreach ($paths as $i => $path) {
         if (!$latest && $this->resolvedPathCache->has($path, 'target', 10)) {
             $resolved[$i] = $this->resolvedPathCache->get($path, 'target');
             continue;
         }
         list(, $container, $rel) = FileBackend::splitStoragePath($path);
         if ($container === "{$this->repoName}-public") {
             $name = basename($path);
             if (strpos($path, '!') !== false) {
                 $sha1 = $db->selectField('oldimage', 'oi_sha1', array('oi_archive_name' => $name), __METHOD__);
             } else {
                 $sha1 = $db->selectField('image', 'img_sha1', array('img_name' => $name), __METHOD__);
             }
             if (!strlen($sha1)) {
                 $resolved[$i] = $path;
                 // give up
                 continue;
             }
             $resolved[$i] = $this->getPathForSHA1($sha1);
             $this->resolvedPathCache->set($path, 'target', $resolved[$i]);
         } elseif ($container === "{$this->repoName}-deleted") {
             $name = basename($path);
             // <hash>.<ext>
             $sha1 = substr($name, 0, strpos($name, '.'));
             // ignore extension
             $resolved[$i] = $this->getPathForSHA1($sha1);
             $this->resolvedPathCache->set($path, 'target', $resolved[$i]);
         } else {
             $resolved[$i] = $path;
         }
     }
     $res = array();
     foreach ($paths as $i => $path) {
         $res[$i] = $resolved[$i];
     }
     return $res;
 }
 /**
  * Pop a job off one of the job queues
  *
  * This pops a job off a queue as specified by $wgJobTypeConf and
  * updates the aggregate job queue information cache as needed.
  *
  * @param int|string $qtype JobQueueGroup::TYPE_* constant or job type string
  * @param int $flags Bitfield of JobQueueGroup::USE_* constants
  * @param array $blacklist List of job types to ignore
  * @return Job|bool Returns false on failure
  */
 public function pop($qtype = self::TYPE_DEFAULT, $flags = 0, array $blacklist = array())
 {
     $job = false;
     if (is_string($qtype)) {
         // specific job type
         if (!in_array($qtype, $blacklist)) {
             $job = $this->get($qtype)->pop();
             if (!$job) {
                 JobQueueAggregator::singleton()->notifyQueueEmpty($this->wiki, $qtype);
             }
         }
     } else {
         // any job in the "default" jobs types
         if ($flags & self::USE_CACHE) {
             if (!$this->cache->has('queues-ready', 'list', self::PROC_CACHE_TTL)) {
                 $this->cache->set('queues-ready', 'list', $this->getQueuesWithJobs());
             }
             $types = $this->cache->get('queues-ready', 'list');
         } else {
             $types = $this->getQueuesWithJobs();
         }
         if ($qtype == self::TYPE_DEFAULT) {
             $types = array_intersect($types, $this->getDefaultQueueTypes());
         }
         $types = array_diff($types, $blacklist);
         // avoid selected types
         shuffle($types);
         // avoid starvation
         foreach ($types as $type) {
             // for each queue...
             $job = $this->get($type)->pop();
             if ($job) {
                 // found
                 break;
             } else {
                 // not found
                 JobQueueAggregator::singleton()->notifyQueueEmpty($this->wiki, $type);
                 $this->cache->clear('queues-ready');
             }
         }
     }
     return $job;
 }
	/**
	 * Get a Swift container object, possibly from process cache.
	 * Use $reCache if the file count or byte count is needed.
	 *
	 * @param string $container Container name
	 * @param bool $bypassCache Bypass all caches and load from Swift
	 * @return CF_Container
	 * @throws CloudFilesException
	 */
	protected function getContainer( $container, $bypassCache = false ) {
		$conn = $this->getConnection(); // Swift proxy connection
		if ( $bypassCache ) { // purge cache
			$this->connContainerCache->clear( $container );
		} elseif ( !$this->connContainerCache->has( $container, 'obj' ) ) {
			$this->primeContainerCache( array( $container ) ); // check persistent cache
		}
		if ( !$this->connContainerCache->has( $container, 'obj' ) ) {
			$contObj = $conn->get_container( $container );
			// NoSuchContainerException not thrown: container must exist
			$this->connContainerCache->set( $container, 'obj', $contObj ); // cache it
			if ( !$bypassCache ) {
				$this->setContainerCache( $container, // update persistent cache
					array( 'bytes' => $contObj->bytes_used, 'count' => $contObj->object_count )
				);
			}
		}
		return $this->connContainerCache->get( $container, 'obj' );
	}
Beispiel #9
0
 /**
  * @see FileBackend::getLocalReferenceMulti()
  * @return Array
  */
 public final function getLocalReferenceMulti(array $params)
 {
     wfProfileIn(__METHOD__);
     wfProfileIn(__METHOD__ . '-' . $this->name);
     $params = $this->setConcurrencyFlags($params);
     $fsFiles = array();
     // (path => FSFile)
     $latest = !empty($params['latest']);
     // use latest data?
     // Reuse any files already in process cache...
     foreach ($params['srcs'] as $src) {
         $path = self::normalizeStoragePath($src);
         if ($path === null) {
             $fsFiles[$src] = null;
             // invalid storage path
         } elseif ($this->expensiveCache->has($path, 'localRef')) {
             $val = $this->expensiveCache->get($path, 'localRef');
             // If we want the latest data, check that this cached
             // value was in fact fetched with the latest available data.
             if (!$latest || $val['latest']) {
                 $fsFiles[$src] = $val['object'];
             }
         }
     }
     // Fetch local references of any remaning files...
     $params['srcs'] = array_diff($params['srcs'], array_keys($fsFiles));
     foreach ($this->doGetLocalReferenceMulti($params) as $path => $fsFile) {
         $fsFiles[$path] = $fsFile;
         if ($fsFile) {
             // update the process cache...
             $this->expensiveCache->set($path, 'localRef', array('object' => $fsFile, 'latest' => $latest));
         }
     }
     wfProfileOut(__METHOD__ . '-' . $this->name);
     wfProfileOut(__METHOD__);
     return $fsFiles;
 }