Made the "bypassCache" flag for file locator methods use the master DB
authorAaron Schulz <aschulz@wikimedia.org>
Thu, 5 Mar 2015 01:02:05 +0000 (17:02 -0800)
committerAaron Schulz <aschulz@wikimedia.org>
Thu, 5 Mar 2015 01:02:05 +0000 (17:02 -0800)
* Added a File::load() stub method
* Cleaned up the File loading flags bitfield a bit

bug: T89184
Change-Id: I1aa4b096c0cad5f5ca34321cc897019005c53a76

includes/GlobalFunctions.php
includes/filerepo/FileRepo.php
includes/filerepo/RepoGroup.php
includes/filerepo/file/File.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/OldLocalFile.php

index 1d44038..883153f 100644 (file)
@@ -3650,19 +3650,7 @@ function wfGetLBFactory() {
  * Shortcut for RepoGroup::singleton()->findFile()
  *
  * @param string $title String or Title object
- * @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.
- *
- *     bypassCache:    If true, do not use the process-local cache of File objects
- *
+ * @param array $options Associative array of options (see RepoGroup::findFile)
  * @return File|bool File, or false if the file does not exist
  */
 function wfFindFile( $title, $options = array() ) {
index d1a16b5..01495a4 100644 (file)
@@ -406,6 +406,7 @@ class FileRepo {
         *   private:        If true, return restricted (deleted) files if the current
         *                   user is allowed to view them. Otherwise, such files will not
         *                   be found. If a User object, use that user instead of the current.
+        *   bypassCache:    If true, do not use the process/persistent cache of File objects
         * @return File|bool False on failure
         */
        public function findFile( $title, $options = array() ) {
@@ -414,17 +415,20 @@ class FileRepo {
                        return false;
                }
                $time = isset( $options['time'] ) ? $options['time'] : false;
+               $flags = !empty( $options['bypassCache'] ) ? File::READ_LATEST : 0;
                # First try the current version of the file to see if it precedes the timestamp
                $img = $this->newFile( $title );
                if ( !$img ) {
                        return false;
                }
+               $img->load( $flags );
                if ( $img->exists() && ( !$time || $img->getTimestamp() == $time ) ) {
                        return $img;
                }
                # Now try an old version of the file
                if ( $time !== false ) {
                        $img = $this->newFile( $title, $time );
+                       $img->load( $flags );
                        if ( $img && $img->exists() ) {
                                if ( !$img->isDeleted( File::DELETED_FILE ) ) {
                                        return $img; // always OK
@@ -445,6 +449,7 @@ class FileRepo {
                $redir = $this->checkRedirect( $title );
                if ( $redir && $title->getNamespace() == NS_FILE ) {
                        $img = $this->newFile( $redir );
+                       $img->load( $flags );
                        if ( !$img ) {
                                return false;
                        }
index fab4216..6ac00de 100644 (file)
@@ -114,7 +114,7 @@ class RepoGroup {
         *   private:        If true, return restricted (deleted) files if the current
         *                   user is allowed to view them. Otherwise, such files will not
         *                   be found.
-        *   bypassCache:    If true, do not use the process-local cache of File objects
+        *   bypassCache:    If true, do not use the process/persistent cache of File objects
         * @return File|bool False if title is not found
         */
        function findFile( $title, $options = array() ) {
index 2721693..4fd332b 100644 (file)
@@ -47,7 +47,7 @@
  *
  * @ingroup FileAbstraction
  */
-abstract class File {
+abstract class File implements IDBAccessObject {
        // Bitfield values akin to the Revision deletion constants
        const DELETED_FILE = 1;
        const DELETED_COMMENT = 2;
@@ -836,6 +836,18 @@ abstract class File {
                return false;
        }
 
+       /**
+        * Load any lazy-loaded file object fields from source
+        *
+        * This is only useful when setting $flags
+        *
+        * Overridden by LocalFile to actually query the DB
+        *
+        * @param integer $flags Bitfield of File::READ_* constants
+        */
+       public function load( $flags = 0 ) {
+       }
+
        /**
         * Returns true if file exists in the repository.
         *
index 699c915..3056ad8 100644 (file)
@@ -127,8 +127,8 @@ class LocalFile extends File {
        /** @var int UNIX timestamp of last markVolatile() call */
        private $lastMarkedVolatile = 0;
 
-       const LOAD_ALL = 1; // integer; load all the lazy fields too (like metadata)
-       const LOAD_VIA_SLAVE = 2; // integer; use a slave to load the data
+       // @note: higher than IDBAccessObject constants
+       const LOAD_ALL = 16; // integer; load all the lazy fields too (like metadata)
 
        const VOLATILE_TTL = 300; // integer; seconds
 
@@ -387,9 +387,9 @@ class LocalFile extends File {
                $this->dataLoaded = true;
                $this->extraDataLoaded = true;
 
-               $dbr = ( $flags & self::LOAD_VIA_SLAVE )
-                       ? $this->repo->getSlaveDB()
-                       : $this->repo->getMasterDB();
+               $dbr = ( $flags & self::READ_LATEST )
+                       ? $this->repo->getMasterDB()
+                       : $this->repo->getSlaveDB();
 
                $row = $dbr->selectRow( 'image', $this->getCacheFields( 'img_' ),
                        array( 'img_name' => $this->getName() ), $fname );
@@ -530,13 +530,18 @@ class LocalFile extends File {
         */
        function load( $flags = 0 ) {
                if ( !$this->dataLoaded ) {
-                       if ( !$this->loadFromCache() ) {
-                               $this->loadFromDB( $this->isVolatile() ? 0 : self::LOAD_VIA_SLAVE );
+                       if ( ( $flags & self::READ_LATEST ) || !$this->loadFromCache() ) {
+                               // b/c for now for data consistency
+                               if ( $this->isVolatile() ) {
+                                       $flags |= self::READ_LATEST;
+                               }
+                               $this->loadFromDB( $flags );
                                $this->saveToCache();
                        }
                        $this->dataLoaded = true;
                }
                if ( ( $flags & self::LOAD_ALL ) && !$this->extraDataLoaded ) {
+                       // @note: loads on name/timestamp to reduce race condition problems
                        $this->loadExtraFromDB();
                }
        }
index 73c614a..fd92e11 100644 (file)
@@ -175,10 +175,12 @@ class OldLocalFile extends LocalFile {
        }
 
        function loadFromDB( $flags = 0 ) {
-
                $this->dataLoaded = true;
 
-               $dbr = $this->repo->getSlaveDB();
+               $dbr = ( $flags & self::READ_LATEST )
+                       ? $this->repo->getMasterDB()
+                       : $this->repo->getSlaveDB();
+
                $conds = array( 'oi_name' => $this->getName() );
                if ( is_null( $this->requestedTime ) ) {
                        $conds['oi_archive_name'] = $this->archive_name;