r106956 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r106955‎ | r106956 | r106957 >
Date:16:50, 21 December 2011
Author:j
Status:resolved (Comments)
Tags:
Comment:
Encode videos in temp and only add to FileRepo once done.
Modified paths:
  • /trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php (modified) (history)
  • /trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php (modified) (history)

Diff [purge]

Index: trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php
@@ -28,9 +28,15 @@
2929 private function output( $msg ){
3030 print $msg . "\n";
3131 }
 32+ private function getFile() {
 33+ if( !$this->file){
 34+ $this->file = wfLocalFile( $this->title );
 35+ }
 36+ return $this->file;
 37+ }
3238 private function getTargetEncodePath(){
3339 if( !$this->targetEncodePath ){
34 - $file = wfLocalFile( $this->title );
 40+ $file = $this->getFile();
3541 $transcodeKey = $this->params[ 'transcodeKey' ];
3642 $this->targetEncodePath = WebVideoTranscode::getTargetEncodePath( $file, $transcodeKey );
3743 }
@@ -39,7 +45,7 @@
4046 private function getSourceFilePath(){
4147 if( !$this->sourceFilePath ){
4248 $file = wfLocalFile( $this->title );
43 - $this->sourceFilePath = $file->getPath();
 49+ $this->sourceFilePath = $file->getLocalRefPath();
4450 }
4551 return $this->sourceFilePath;
4652 }
@@ -139,25 +145,51 @@
140146 // If status is oky and file exists and is larger than 0 bytes
141147 if( $status === true && is_file( $this->getTargetEncodePath() ) && filesize( $this->getTargetEncodePath() ) > 0 ){
142148 $finalDerivativeFilePath = WebVideoTranscode::getDerivativeFilePath( $file, $transcodeKey);
143 - wfSuppressWarnings();
144 - $status = rename( $this->getTargetEncodePath(), $finalDerivativeFilePath );
145 - $bitrate = round( intval( filesize( $finalDerivativeFilePath ) / $file->getLength() ) * 8 );
146 - wfRestoreWarnings();
147 - // Update the transcode table with success time:
148 - $dbw->update(
149 - 'transcode',
150 - array(
151 - 'transcode_time_success' => $db->timestamp(),
152 - 'transcode_final_bitrate' => $bitrate
153 - ),
154 - array(
155 - 'transcode_image_name' => $this->title->getDBkey(),
156 - 'transcode_key' => $transcodeKey,
157 - ),
158 - __METHOD__,
159 - array( 'LIMIT' => 1 )
160 - );
161 - WebVideoTranscode::invalidatePagesWithFile( $this->title );
 149+ //wfSuppressWarnings();
 150+ // @TODO: use a FileRepo store function
 151+ $op = array( 'op' => 'store',
 152+ 'src' => $this->getTargetEncodePath(), 'dst' => $finalDerivativeFilePath, 'overwriteDest' => true );
 153+ // Copy derivaitve from the FS into storage at $finalDerivativeFilePath
 154+ $opts = array( 'ignoreErrors' => true, 'nonLocking' => true ); // performance
 155+ $file = $this->getFile();
 156+ $status = $file->getRepo()->getBackend()->doOperation( $op, $opts );
 157+ if (!$status->isOK() ) {
 158+ // Update the transcode table with failure time and error
 159+ $dbw->update(
 160+ 'transcode',
 161+ array(
 162+ 'transcode_time_error' => $db->timestamp(),
 163+ 'transcode_error' => $status
 164+ ),
 165+ array(
 166+ 'transcode_image_name' => $this->title->getDBkey(),
 167+ 'transcode_key' => $transcodeKey
 168+ ),
 169+ __METHOD__,
 170+ array( 'LIMIT' => 1 )
 171+ );
 172+ // no need to invalidate all pages with video. Because all pages remain valid ( no $transcodeKey derivative )
 173+ // just clear the file page ( so that the transcode table shows the error )
 174+ $this->title->invalidateCache();
 175+ } else {
 176+ $bitrate = round( intval( filesize( $finalDerivativeFilePath ) / $file->getLength() ) * 8 );
 177+ //wfRestoreWarnings();
 178+ // Update the transcode table with success time:
 179+ $dbw->update(
 180+ 'transcode',
 181+ array(
 182+ 'transcode_time_success' => $db->timestamp(),
 183+ 'transcode_final_bitrate' => $bitrate
 184+ ),
 185+ array(
 186+ 'transcode_image_name' => $this->title->getDBkey(),
 187+ 'transcode_key' => $transcodeKey,
 188+ ),
 189+ __METHOD__,
 190+ array( 'LIMIT' => 1 )
 191+ );
 192+ WebVideoTranscode::invalidatePagesWithFile( $this->title );
 193+ }
162194 } else {
163195 // Update the transcode table with failure time and error
164196 $dbw->update(
@@ -204,7 +236,7 @@
205237 global $wgFFmpegLocation;
206238
207239 // Set up the base command
208 - $cmd = wfEscapeShellArg( $wgFFmpegLocation ) . ' -i ' . wfEscapeShellArg( $this->getSourceFilePath() );
 240+ $cmd = wfEscapeShellArg( $wgFFmpegLocation ) . ' -y -i ' . wfEscapeShellArg( $this->getSourceFilePath() );
209241
210242 if( isset($options['preset']) ){
211243 if ($options['preset'] == "360p") {
Index: trunk/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php
@@ -156,11 +156,15 @@
157157 * @return the local target encode path
158158 */
159159 static public function getTargetEncodePath( &$file, $transcodeKey ){
160 - // TODO probably should use some other temporary non-web accessible location for
161 - // in-progress encodes, its nice having it publicly accessible for debugging though
162160 $filePath = self::getDerivativeFilePath( $file, $transcodeKey );
163161 $ext = strtolower( pathinfo( "$filePath", PATHINFO_EXTENSION ) );
164 - return "{$filePath}.part.{$ext}";
 162+
 163+ // Create a temp FS file with the same extension
 164+ $tmpFile = TempFSFile::factory( 'transcode_' . $transcodeKey, $ext);
 165+ if ( !$tmpFile ) {
 166+ return False;
 167+ }
 168+ return $tmpFile->getPath(); //path with 0-byte temp file
165169 }
166170
167171 /**

Follow-up revisions

RevisionCommit summaryAuthorDate
r107058bind temp file and purge after encoding to prevent deletion/race condition on...j11:43, 22 December 2011

Comments

#Comment by Aaron Schulz (talk | contribs)   22:10, 21 December 2011

In 'static public function getTargetEncodePath' you should call $tmpFile->bind( $file ). Otherwise, the file gets deleted when getTargetEncodePath() returns out and you have a possibly race condition on the temp file name (though not very likely to be a problem). Also, it means the temp transcode file won't get cleared out.

Status & tagging log