From: Aaron Schulz Date: Tue, 22 Apr 2014 16:38:51 +0000 (-0700) Subject: Made LocalFile::loadExtraFromDB() handle re-upload race conditions X-Git-Tag: 1.31.0-rc.0~16016^2 X-Git-Url: https://git.cyclocoop.org//%22?a=commitdiff_plain;h=3eced85d6009614594d2be7b7cd4998cf3cf229f;p=lhc%2Fweb%2Fwiklou.git Made LocalFile::loadExtraFromDB() handle re-upload race conditions Change-Id: I99a39c3d2b5d7a227be9b11a2f23c534ea4739d9 --- diff --git a/includes/filerepo/file/LocalFile.php b/includes/filerepo/file/LocalFile.php index f89dc3d285..3d6f24e0bc 100644 --- a/includes/filerepo/file/LocalFile.php +++ b/includes/filerepo/file/LocalFile.php @@ -417,19 +417,13 @@ class LocalFile extends File { # Unconditionally set loaded=true, we don't want the accessors constantly rechecking $this->extraDataLoaded = true; - $dbr = $this->repo->getSlaveDB(); - // In theory the file could have just been renamed/deleted...oh well - $row = $dbr->selectRow( 'image', $this->getLazyCacheFields( 'img_' ), - array( 'img_name' => $this->getName() ), $fname ); - - if ( !$row ) { // fallback to master - $dbr = $this->repo->getMasterDB(); - $row = $dbr->selectRow( 'image', $this->getLazyCacheFields( 'img_' ), - array( 'img_name' => $this->getName() ), $fname ); + $fieldMap = $this->loadFieldsWithTimestamp( $this->repo->getSlaveDB(), $fname ); + if ( !$fieldMap ) { + $fieldMap = $this->loadFieldsWithTimestamp( $this->repo->getMasterDB(), $fname ); } - if ( $row ) { - foreach ( $this->unprefixRow( $row, 'img_' ) as $name => $value ) { + if ( $fieldMap ) { + foreach ( $fieldMap as $name => $value ) { $this->$name = $value; } } else { @@ -440,6 +434,32 @@ class LocalFile extends File { wfProfileOut( $fname ); } + /** + * @param DatabaseBase $dbr + * @param string $fname + * @return array|false + */ + private function loadFieldsWithTimestamp( $dbr, $fname ) { + $fieldMap = false; + + $row = $dbr->selectRow( 'image', $this->getLazyCacheFields( 'img_' ), + array( 'img_name' => $this->getName(), 'img_timestamp' => $this->getTimestamp() ), + $fname ); + if ( $row ) { + $fieldMap = $this->unprefixRow( $row, 'img_' ); + } else { + # File may have been uploaded over in the meantime; check the old versions + $row = $dbr->selectRow( 'oldimage', $this->getLazyCacheFields( 'oi_' ), + array( 'oi_name' => $this->getName(), 'oi_timestamp' => $this->getTimestamp() ), + $fname ); + if ( $row ) { + $fieldMap = $this->unprefixRow( $row, 'oi_' ); + } + } + + return $fieldMap; + } + /** * @param array $row Row * @param string $prefix @@ -1911,10 +1931,14 @@ class LocalFile extends File { $key = $this->repo->getSharedCacheKey( 'file-volatile', md5( $this->getName() ) ); if ( $key ) { - if ( $this->lastMarkedVolatile && ( time() - $this->lastMarkedVolatile ) <= self::VOLATILE_TTL ) { + if ( $this->lastMarkedVolatile + && ( time() - $this->lastMarkedVolatile ) <= self::VOLATILE_TTL + ) { return true; // sanity } - return ( $wgMemc->get( $key ) !== false ); + $volatileTimestamp = (int)$wgMemc->get( $key ); + $this->lastMarkedVolatile = max( $this->lastMarkedVolatile, $volatileTimestamp ); + return ( $volatileTimestamp != 0 ); } return false;