r105846 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r105845‎ | r105846 | r105847 >
Date:00:50, 12 December 2011
Author:aaron
Status:deferred
Tags:
Comment:
* Removed 'cache' as an option to DBLockManager (always used now); makes construction simpler
* Made TempFSFile::factory() perform more consistently and avoided race condition with rename() (on UNIX)
* Use file basename for FSFileBackend local copy backup prefixes (might help for recovery)
* Remove now-unneeded gmdate() call in File::maybeDoTransform which was causing regenerations for no reason
* Avoid creating temp files in File::maybeDoTransform when we are just going to call getTransform() and not actually write anything
* Updated EXIF tests to use FORCE_RENDER since they require an output FS file
Modified paths:
  • /branches/FileBackend/phase3/includes/filerepo/backend/FSFileBackend.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/backend/LockManager.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/file/File.php (modified) (history)
  • /branches/FileBackend/phase3/includes/filerepo/file/TempFSFile.php (modified) (history)
  • /branches/FileBackend/phase3/tests/phpunit/includes/media/ExifRotationTest.php (modified) (history)

Diff [purge]

Index: branches/FileBackend/phase3/tests/phpunit/includes/media/ExifRotationTest.php
@@ -16,9 +16,9 @@
1717 'containerPaths' => array( 'images-thumb' => $tmpDir, 'data' => $filePath )
1818 ) );
1919 $this->repo = new FSRepo( array(
20 - 'name' => 'temp',
21 - 'url' => 'http://localhost/thumbtest',
22 - 'backend' => $this->backend
 20+ 'name' => 'temp',
 21+ 'url' => 'http://localhost/thumbtest',
 22+ 'backend' => $this->backend
2323 ) );
2424 if ( !wfDl( 'exif' ) ) {
2525 $this->markTestSkipped( "This test needs the exif extension." );
@@ -73,7 +73,7 @@
7474 }
7575
7676 $file = $this->dataFile( $name, $type );
77 - $thumb = $file->transform( $params, File::RENDER_NOW );
 77+ $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE );
7878
7979 $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" );
8080 $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
@@ -166,7 +166,7 @@
167167 }
168168
169169 $file = $this->dataFile( $name, $type );
170 - $thumb = $file->transform( $params, File::RENDER_NOW );
 170+ $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE );
171171
172172 $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" );
173173 $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
Index: branches/FileBackend/phase3/includes/filerepo/file/TempFSFile.php
@@ -26,21 +26,23 @@
2727 * @return TempFSFile|null
2828 */
2929 public static function factory( $prefix, $extension = '' ) {
30 - $tmpDest = tempnam( wfTempDir(), $prefix );
31 - if ( $tmpDest === false ) {
32 - return null;
33 - }
34 - if ( $extension != '' ) {
35 - $path = "{$tmpDest}.{$extension}";
36 - if ( !rename( $tmpDest, $path ) ) {
37 - return null;
 30+ $base = wfTempDir() . '/' . $prefix . dechex( mt_rand( 0, 99999999 ) );
 31+ $ext = ( $extension != '' ) ? ".{$extension}" : "";
 32+ for ( $attempt = 1; true; $attempt++ ) {
 33+ $path = "{$base}-{$attempt}{$ext}";
 34+ wfSuppressWarnings();
 35+ $newFileHandle = fopen( $path, 'x' );
 36+ wfRestoreWarnings();
 37+ if ( $newFileHandle ) {
 38+ fclose( $newFileHandle );
 39+ break; // got it
3840 }
39 - } else {
40 - $path = $tmpDest;
 41+ if ( $attempt >= 15 ) {
 42+ return null; // give up
 43+ }
4144 }
4245 $tmpFile = new self( $path );
43 - self::$instances[] = $tmpFile;
44 -
 46+ self::$instances[] = $tmpFile; // defer purge till shutdown
4547 return $tmpFile;
4648 }
4749
Index: branches/FileBackend/phase3/includes/filerepo/file/File.php
@@ -757,30 +757,31 @@
758758 global $wgIgnoreImageErrors, $wgThumbnailEpoch;
759759
760760 $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path
761 - // Create a temp FS file with the same extension
762 - $tmpFile = TempFSFile::factory( 'transform', $this->getExtension() );
763 - if ( !$tmpFile ) {
764 - return new MediaTransformError( 'thumbnail_error',
765 - $params['width'], 0, wfMsg( 'thumbnail-temp-create' ) );
766 - }
767 - $tmpThumbPath = $tmpFile->getPath(); // path of 0-byte temp file
768761
769762 if ( $this->repo && $this->repo->canTransformVia404() && !( $flags & self::RENDER_NOW ) ) {
770763 wfDebug( __METHOD__ . " transformation deferred." );
771 - return $this->handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $params );
 764+ return $this->handler->getTransform( $this, false, $thumbUrl, $params );
772765 }
773766
774767 wfDebug( __METHOD__.": Doing stat for $thumbPath\n" );
775768 $this->migrateThumbFile( $thumbName );
776769 if ( $this->repo->fileExists( $thumbPath ) && !( $flags & self::RENDER_FORCE ) ) {
777 - $ts = $this->repo->getFileTimestamp( $thumbPath );
778 - if ( $ts !== false && gmdate( 'YmdHis', $ts ) >= $wgThumbnailEpoch ) {
779 - return $this->handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $params );
 770+ $timestamp = $this->repo->getFileTimestamp( $thumbPath );
 771+ if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) {
 772+ return $this->handler->getTransform( $this, false, $thumbUrl, $params );
780773 }
781774 } elseif ( $flags & self::RENDER_FORCE ) {
782775 wfDebug( __METHOD__ . " forcing rendering per flag File::RENDER_FORCE\n" );
783776 }
784777
 778+ // Create a temp FS file with the same extension
 779+ $tmpFile = TempFSFile::factory( 'transform_', $this->getExtension() );
 780+ if ( !$tmpFile ) {
 781+ return new MediaTransformError( 'thumbnail_error',
 782+ $params['width'], 0, wfMsg( 'thumbnail-temp-create' ) );
 783+ }
 784+ $tmpThumbPath = $tmpFile->getPath(); // path of 0-byte temp file
 785+
785786 // Actually render the thumbnail
786787 $thumb = $this->handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $params );
787788
Index: branches/FileBackend/phase3/includes/filerepo/backend/FSFileBackend.php
@@ -484,7 +484,7 @@
485485 $i = strrpos( $source, '.' );
486486 $ext = strtolower( $i ? substr( $source, $i + 1 ) : '' );
487487 // Create a new temporary file...
488 - $tmpFile = TempFSFile::factory( 'localcopy_', $ext );
 488+ $tmpFile = TempFSFile::factory( wfBaseName( $source ) . '_', $ext );
489489 if ( !$tmpFile ) {
490490 return null;
491491 }
Index: branches/FileBackend/phase3/includes/filerepo/backend/LockManager.php
@@ -318,8 +318,6 @@
319319 * 'safeDelay' : Seconds to mistrust a DB after restart/query loss. [optional]
320320 * This should reflect the highest max_execution_time that PHP
321321 * scripts might use on a wiki. Locks are lost on DB server restart.
322 - * 'cache' : $wgMemc (if set to a global memcached instance). [optional]
323 - * This tracks peer DBs that couldn't be queried recently.
324322 *
325323 * @param Array $config
326324 */
@@ -341,11 +339,7 @@
342340 ? $config['safeDelay']
343341 : max( $this->cliTimeout, $this->webTimeout ); // cover worst case
344342
345 - if ( isset( $config['cache'] ) && $config['cache'] instanceof BagOStuff ) {
346 - $this->statusCache = $config['cache'];
347 - } else {
348 - $this->statusCache = null;
349 - }
 343+ $this->statusCache = wfGetMainCache(); // tracks peers that couldn't be queried recently
350344 }
351345
352346 protected function doLock( array $keys, $type ) {
@@ -687,13 +681,13 @@
688682 }
689683 # Block new writers...
690684 $db->insert( 'file_locks_shared', $data, __METHOD__ );
691 - # Wait on any existing writers...
692 - $db->query( "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED" );
 685+ # Bail if there are any existing writers...
 686+ $db->query( "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;" );
693687 $ok = !$db->selectField( 'file_locks_exclusive', '1',
694688 array( 'fle_key' => $keys ),
695689 __METHOD__
696690 );
697 - $db->query( "SET SESSION TRANSACTION ISOLATION LEVEL {$this->trxIso[$lockDb]}" );
 691+ $db->query( "SET SESSION TRANSACTION ISOLATION LEVEL {$this->trxIso[$lockDb]};" );
698692 } elseif ( $type == self::LOCK_EX ) { // writer locks
699693 $db = $this->getConnection( $lockDb );
700694 $data = array();
@@ -702,13 +696,13 @@
703697 }
704698 # Block new readers/writers and wait on any existing writers
705699 $db->insert( 'file_locks_exclusive', $data, __METHOD__ );
706 - # Wait on any existing readers...
707 - $db->query( "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED" );
 700+ # Bail if there are any existing readers...
 701+ $db->query( "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;" );
708702 $ok = !$db->selectField( 'file_locks_shared', '1',
709703 array( 'fls_key' => $keys ),
710704 __METHOD__
711705 );
712 - $db->query( "SET SESSION TRANSACTION ISOLATION LEVEL {$this->trxIso[$lockDb]}" );
 706+ $db->query( "SET SESSION TRANSACTION ISOLATION LEVEL {$this->trxIso[$lockDb]};" );
713707 }
714708 return $ok;
715709 }

Status & tagging log