Merge "Wrap djvu large local copy downloads in pool counter"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sun, 13 Apr 2014 22:30:40 +0000 (22:30 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sun, 13 Apr 2014 22:30:40 +0000 (22:30 +0000)
1  2 
includes/media/DjVu.php

diff --combined includes/media/DjVu.php
@@@ -177,7 -177,33 +177,33 @@@ class DjVuHandler extends ImageHandler 
                        );
                }
  
-               $srcPath = $image->getLocalRefPath();
+               // Get local copy source for shell scripts
+               // Thumbnail extraction is very inefficient for large files.
+               // Provide a way to pool count limit the number of downloaders.
+               if ( $image->getSize() >= 1e7 ) { // 10MB
+                       $work = new PoolCounterWorkViaCallback( 'GetLocalFileCopy', sha1( $image->getName() ),
+                               array(
+                                       'doWork' => function() use ( $image ) {
+                                               return $image->getLocalRefPath();
+                                       }
+                               )
+                       );
+                       $srcPath = $work->execute();
+               } else {
+                       $srcPath = $image->getLocalRefPath();
+               }
+               if ( $srcPath === false ) { // Failed to get local copy
+                       wfDebugLog( 'thumbnail',
+                               sprintf( 'Thumbnail failed on %s: could not get local copy of "%s"',
+                                       wfHostname(), $image->getName() ) );
+                       return new MediaTransformError( 'thumbnail_error',
+                               $params['width'], $params['height'],
+                               wfMessage( 'filemissing' )->text()
+                       );
+               }
                # Use a subshell (brackets) to aggregate stderr from both pipeline commands
                # before redirecting it to the overall stdout. This works in both Linux and Windows XP.
                $cmd = '(' . wfEscapeShellArg(
                return $deja;
        }
  
 +      /**
 +       * Get metadata, unserializing it if neccessary.
 +       *
 +       * @param File $file The DjVu file in question
 +       * @return String XML metadata as a string.
 +       */
 +      private function getUnserializedMetadata( File $file ) {
 +              $metadata = $file->getMetadata();
 +              if ( substr( $metadata, 0, 3 ) === '<?xml' ) {
 +                      // Old style. Not serialized but instead just a raw string of XML.
 +                      return $metadata;
 +              }
 +
 +              wfSuppressWarnings();
 +              $unser = unserialize( $metadata );
 +              wfRestoreWarnings();
 +              if ( is_array( $unser ) ) {
 +                      return $unser['xml'];
 +              }
 +
 +              // unserialize failed. Guess it wasn't really serialized after all,
 +              return $metadata;
 +      }
 +
        /**
         * Cache a document tree for the DjVu XML metadata
         * @param File $image
                        return $image->dejaMetaTree;
                }
  
 -              $metadata = $image->getMetadata();
 +              $metadata = $this->getUnserializedMetadata( $image );
                if ( !$this->isMetadataValid( $image, $metadata ) ) {
                        wfDebug( "DjVu XML metadata is invalid or missing, should have been fixed in upgradeRow\n" );
  
        function getMetadata( $image, $path ) {
                wfDebug( "Getting DjVu metadata for $path\n" );
  
 -              return $this->getDjVuImage( $image, $path )->retrieveMetaData();
 +              $xml = $this->getDjVuImage( $image, $path )->retrieveMetaData();
 +              if ( $xml === false ) {
 +                      return false;
 +              } else {
 +                      return serialize( array( 'xml' => $xml ) );
 +              }
        }
  
        function getMetadataType( $image ) {