diff options
Diffstat (limited to 'includes/job/jobs')
-rw-r--r-- | includes/job/jobs/AssembleUploadChunksJob.php | 19 | ||||
-rw-r--r-- | includes/job/jobs/DoubleRedirectJob.php | 29 | ||||
-rw-r--r-- | includes/job/jobs/DuplicateJob.php | 2 | ||||
-rw-r--r-- | includes/job/jobs/EnotifNotifyJob.php | 2 | ||||
-rw-r--r-- | includes/job/jobs/HTMLCacheUpdateJob.php | 25 | ||||
-rw-r--r-- | includes/job/jobs/NullJob.php | 16 | ||||
-rw-r--r-- | includes/job/jobs/PublishStashedFileJob.php | 22 | ||||
-rw-r--r-- | includes/job/jobs/RefreshLinksJob.php | 28 | ||||
-rw-r--r-- | includes/job/jobs/UploadFromUrlJob.php | 7 |
9 files changed, 99 insertions, 51 deletions
diff --git a/includes/job/jobs/AssembleUploadChunksJob.php b/includes/job/jobs/AssembleUploadChunksJob.php index c5dd9eaa..6237e568 100644 --- a/includes/job/jobs/AssembleUploadChunksJob.php +++ b/includes/job/jobs/AssembleUploadChunksJob.php @@ -42,6 +42,15 @@ class AssembleUploadChunksJob extends Job { return false; } + if ( count( $_SESSION ) === 0 ) { + // Empty session probably indicates that we didn't associate + // with the session correctly. Note that being able to load + // the user does not necessarily mean the session was loaded. + // Most likely cause by suhosin.session.encrypt = On. + $this->setLastError( "Error associating with user session. Try setting suhosin.session.encrypt = Off" ); + return false; + } + UploadBase::setSessionStatus( $this->params['filekey'], array( 'result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood() ) @@ -82,11 +91,11 @@ class AssembleUploadChunksJob extends Job { UploadBase::setSessionStatus( $this->params['filekey'], array( - 'result' => 'Success', - 'stage' => 'assembling', - 'filekey' => $newFileKey, + 'result' => 'Success', + 'stage' => 'assembling', + 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, - 'status' => Status::newGood() + 'status' => Status::newGood() ) ); } catch ( MWException $e ) { @@ -94,7 +103,7 @@ class AssembleUploadChunksJob extends Job { $this->params['filekey'], array( 'result' => 'Failure', - 'stage' => 'assembling', + 'stage' => 'assembling', 'status' => Status::newFatal( 'api-error-stashfailed' ) ) ); diff --git a/includes/job/jobs/DoubleRedirectJob.php b/includes/job/jobs/DoubleRedirectJob.php index 05abeeef..33e749b8 100644 --- a/includes/job/jobs/DoubleRedirectJob.php +++ b/includes/job/jobs/DoubleRedirectJob.php @@ -90,40 +90,40 @@ class DoubleRedirectJob extends Job { $targetRev = Revision::newFromTitle( $this->title, false, Revision::READ_LATEST ); if ( !$targetRev ) { - wfDebug( __METHOD__.": target redirect already deleted, ignoring\n" ); + wfDebug( __METHOD__ . ": target redirect already deleted, ignoring\n" ); return true; } $content = $targetRev->getContent(); $currentDest = $content ? $content->getRedirectTarget() : null; if ( !$currentDest || !$currentDest->equals( $this->redirTitle ) ) { - wfDebug( __METHOD__.": Redirect has changed since the job was queued\n" ); + wfDebug( __METHOD__ . ": Redirect has changed since the job was queued\n" ); return true; } - # Check for a suppression tag (used e.g. in periodically archived discussions) + // Check for a suppression tag (used e.g. in periodically archived discussions) $mw = MagicWord::get( 'staticredirect' ); if ( $content->matchMagicWord( $mw ) ) { - wfDebug( __METHOD__.": skipping: suppressed with __STATICREDIRECT__\n" ); + wfDebug( __METHOD__ . ": skipping: suppressed with __STATICREDIRECT__\n" ); return true; } - # Find the current final destination + // Find the current final destination $newTitle = self::getFinalDestination( $this->redirTitle ); if ( !$newTitle ) { - wfDebug( __METHOD__.": skipping: single redirect, circular redirect or invalid redirect destination\n" ); + wfDebug( __METHOD__ . ": skipping: single redirect, circular redirect or invalid redirect destination\n" ); return true; } if ( $newTitle->equals( $this->redirTitle ) ) { - # The redirect is already right, no need to change it - # This can happen if the page was moved back (say after vandalism) - wfDebug( __METHOD__.": skipping, already good\n" ); + // The redirect is already right, no need to change it + // This can happen if the page was moved back (say after vandalism) + wfDebug( __METHOD__ . " : skipping, already good\n" ); } - # Preserve fragment (bug 14904) + // Preserve fragment (bug 14904) $newTitle = Title::makeTitle( $newTitle->getNamespace(), $newTitle->getDBkey(), $currentDest->getFragment(), $newTitle->getInterwiki() ); - # Fix the text + // Fix the text $newContent = $content->updateRedirect( $newTitle ); if ( $newContent->equals( $content ) ) { @@ -137,11 +137,13 @@ class DoubleRedirectJob extends Job { return false; } - # Save it + // Save it global $wgUser; $oldUser = $wgUser; $wgUser = $user; $article = WikiPage::factory( $this->title ); + + // Messages: double-redirect-fixed-move, double-redirect-fixed-maintenance $reason = wfMessage( 'double-redirect-fixed-' . $this->reason, $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText() )->inContentLanguage()->text(); @@ -161,7 +163,8 @@ class DoubleRedirectJob extends Job { public static function getFinalDestination( $title ) { $dbw = wfGetDB( DB_MASTER ); - $seenTitles = array(); # Circular redirect check + // Circular redirect check + $seenTitles = array(); $dest = false; while ( true ) { diff --git a/includes/job/jobs/DuplicateJob.php b/includes/job/jobs/DuplicateJob.php index 524983b8..be1bfe5c 100644 --- a/includes/job/jobs/DuplicateJob.php +++ b/includes/job/jobs/DuplicateJob.php @@ -45,7 +45,7 @@ final class DuplicateJob extends Job { * @return Job */ public static function newFromJob( Job $job ) { - $djob = new self( $job->getTitle(), $job->getParams(), $job->getId() ); + $djob = new self( $job->getTitle(), $job->getParams(), $job->id ); $djob->command = $job->getType(); $djob->params = is_array( $djob->params ) ? $djob->params : array(); $djob->params = array( 'isDuplicate' => true ) + $djob->params; diff --git a/includes/job/jobs/EnotifNotifyJob.php b/includes/job/jobs/EnotifNotifyJob.php index 2be05b63..bbe988d0 100644 --- a/includes/job/jobs/EnotifNotifyJob.php +++ b/includes/job/jobs/EnotifNotifyJob.php @@ -35,7 +35,7 @@ class EnotifNotifyJob extends Job { function run() { $enotif = new EmailNotification(); // Get the user from ID (rename safe). Anons are 0, so defer to name. - if( isset( $this->params['editorID'] ) && $this->params['editorID'] ) { + if ( isset( $this->params['editorID'] ) && $this->params['editorID'] ) { $editor = User::newFromId( $this->params['editorID'] ); // B/C, only the name might be given. } else { diff --git a/includes/job/jobs/HTMLCacheUpdateJob.php b/includes/job/jobs/HTMLCacheUpdateJob.php index 818c6abf..44c240bb 100644 --- a/includes/job/jobs/HTMLCacheUpdateJob.php +++ b/includes/job/jobs/HTMLCacheUpdateJob.php @@ -79,8 +79,16 @@ class HTMLCacheUpdateJob extends Job { * Update all of the backlinks */ protected function doFullUpdate() { + global $wgMaxBacklinksInvalidate; + # Get an estimate of the number of rows from the BacklinkCache - $numRows = $this->blCache->getNumLinks( $this->params['table'] ); + $max = max( $this->rowsPerJob * 2, $wgMaxBacklinksInvalidate ) + 1; + $numRows = $this->blCache->getNumLinks( $this->params['table'], $max ); + if ( $wgMaxBacklinksInvalidate !== false && $numRows > $wgMaxBacklinksInvalidate ) { + wfDebug( "Skipped HTML cache invalidation of {$this->title->getPrefixedText()}." ); + return true; + } + if ( $numRows > $this->rowsPerJob * 2 ) { # Do fast cached partition $this->insertPartitionJobs(); @@ -90,12 +98,13 @@ class HTMLCacheUpdateJob extends Job { # Check if the row count estimate was correct if ( $titleArray->count() > $this->rowsPerJob * 2 ) { # Not correct, do accurate partition - wfDebug( __METHOD__.": row count estimate was incorrect, repartitioning\n" ); + wfDebug( __METHOD__ . ": row count estimate was incorrect, repartitioning\n" ); $this->insertJobsFromTitles( $titleArray ); } else { $this->invalidateTitles( $titleArray ); // just do the query } } + return true; } @@ -145,7 +154,7 @@ class HTMLCacheUpdateJob extends Job { array( 'table' => $this->params['table'], 'start' => $start, - 'end' => $id - 1 + 'end' => $id - 1 ) + $rootJobParams // carry over information for de-duplication ); $start = $id; @@ -158,16 +167,16 @@ class HTMLCacheUpdateJob extends Job { array( 'table' => $this->params['table'], 'start' => $start, - 'end' => $this->params['end'] + 'end' => $this->params['end'] ) + $rootJobParams // carry over information for de-duplication ); - wfDebug( __METHOD__.": repartitioning into " . count( $jobs ) . " jobs\n" ); + wfDebug( __METHOD__ . ": repartitioning into " . count( $jobs ) . " jobs\n" ); if ( count( $jobs ) < 2 ) { # I don't think this is possible at present, but handling this case # makes the code a bit more robust against future code updates and # avoids a potential infinite loop of repartitioning - wfDebug( __METHOD__.": repartitioning failed!\n" ); + wfDebug( __METHOD__ . ": repartitioning failed!\n" ); $this->invalidateTitles( $titleArray ); } else { JobQueueGroup::singleton()->push( $jobs ); @@ -194,7 +203,7 @@ class HTMLCacheUpdateJob extends Job { array( 'table' => $this->params['table'], 'start' => $start, - 'end' => $end, + 'end' => $end, ) + $rootJobParams // carry over information for de-duplication ); } @@ -245,7 +254,7 @@ class HTMLCacheUpdateJob extends Job { } # Update file cache - if ( $wgUseFileCache ) { + if ( $wgUseFileCache ) { foreach ( $titleArray as $title ) { HTMLFileCache::clearFileCache( $title ); } diff --git a/includes/job/jobs/NullJob.php b/includes/job/jobs/NullJob.php index d282a8e6..b6164a5d 100644 --- a/includes/job/jobs/NullJob.php +++ b/includes/job/jobs/NullJob.php @@ -26,6 +26,22 @@ * in the queue and/or sleep for a brief time period. These can be used * to represent "no-op" jobs or test lock contention and performance. * + * @par Example: + * Inserting a null job in the configured job queue: + * @code + * $ php maintenance/eval.php + * > $queue = JobQueueGroup::singleton(); + * > $job = new NullJob( Title::newMainPage(), array( 'lives' => 10 ) ); + * > $queue->push( $job ); + * @endcode + * You can then confirm the job has been enqueued by using the showJobs.php + * maintenance utility: + * @code + * $ php maintenance/showJobs.php --group + * null: 1 queue; 0 claimed (0 active, 0 abandoned) + * $ + * @endcode + * * @ingroup JobQueue */ class NullJob extends Job { diff --git a/includes/job/jobs/PublishStashedFileJob.php b/includes/job/jobs/PublishStashedFileJob.php index d3feda28..5a24f93c 100644 --- a/includes/job/jobs/PublishStashedFileJob.php +++ b/includes/job/jobs/PublishStashedFileJob.php @@ -42,13 +42,23 @@ class PublishStashedFileJob extends Job { return false; } + if ( count( $_SESSION ) === 0 ) { + // Empty session probably indicates that we didn't associate + // with the session correctly. Note that being able to load + // the user does not necessarily mean the session was loaded. + // Most likely cause by suhosin.session.encrypt = On. + $this->setLastError( "Error associating with user session. Try setting suhosin.session.encrypt = Off" ); + return false; + } + + UploadBase::setSessionStatus( $this->params['filekey'], array( 'result' => 'Poll', 'stage' => 'publish', 'status' => Status::newGood() ) ); $upload = new UploadFromStash( $user ); - // @TODO: initialize() causes a GET, ideally we could frontload the antivirus + // @todo initialize() causes a GET, ideally we could frontload the antivirus // checks and anything else to the stash stage (which includes concatenation and // the local file is thus already there). That way, instead of GET+PUT, there could // just be a COPY operation from the stash to the public zone. @@ -94,11 +104,11 @@ class PublishStashedFileJob extends Job { UploadBase::setSessionStatus( $this->params['filekey'], array( - 'result' => 'Success', - 'stage' => 'publish', - 'filename' => $upload->getLocalFile()->getName(), + 'result' => 'Success', + 'stage' => 'publish', + 'filename' => $upload->getLocalFile()->getName(), 'imageinfo' => $imageInfo, - 'status' => Status::newGood() + 'status' => Status::newGood() ) ); } catch ( MWException $e ) { @@ -106,7 +116,7 @@ class PublishStashedFileJob extends Job { $this->params['filekey'], array( 'result' => 'Failure', - 'stage' => 'publish', + 'stage' => 'publish', 'status' => Status::newFatal( 'api-error-publishfailed' ) ) ); diff --git a/includes/job/jobs/RefreshLinksJob.php b/includes/job/jobs/RefreshLinksJob.php index 9dbe8278..4fc8bac6 100644 --- a/includes/job/jobs/RefreshLinksJob.php +++ b/includes/job/jobs/RefreshLinksJob.php @@ -37,21 +37,18 @@ class RefreshLinksJob extends Job { * @return boolean success */ function run() { - wfProfileIn( __METHOD__ ); - $linkCache = LinkCache::singleton(); $linkCache->clear(); if ( is_null( $this->title ) ) { $this->error = "refreshLinks: Invalid title"; - wfProfileOut( __METHOD__ ); return false; } # Wait for the DB of the current/next slave DB handle to catch up to the master. # This way, we get the correct page_latest for templates or files that just changed # milliseconds ago, having triggered this job to begin with. - if ( isset( $this->params['masterPos'] ) ) { + if ( isset( $this->params['masterPos'] ) && $this->params['masterPos'] !== false ) { wfGetLB()->waitFor( $this->params['masterPos'] ); } @@ -59,13 +56,11 @@ class RefreshLinksJob extends Job { if ( !$revision ) { $this->error = 'refreshLinks: Article not found "' . $this->title->getPrefixedDBkey() . '"'; - wfProfileOut( __METHOD__ ); return false; // XXX: what if it was just deleted? } self::runForTitleInternal( $this->title, $revision, __METHOD__ ); - wfProfileOut( __METHOD__ ); return true; } @@ -101,6 +96,9 @@ class RefreshLinksJob extends Job { $updates = $content->getSecondaryDataUpdates( $title, null, false, $parserOutput ); DataUpdate::runUpdates( $updates ); + + InfoAction::invalidateCache( $title ); + wfProfileOut( $fname ); } } @@ -114,6 +112,8 @@ class RefreshLinksJob extends Job { class RefreshLinksJob2 extends Job { function __construct( $title, $params, $id = 0 ) { parent::__construct( 'refreshLinks2', $title, $params, $id ); + // Base jobs for large templates can easily be de-duplicated + $this->removeDuplicates = !isset( $params['start'] ) && !isset( $params['end'] ); } /** @@ -123,14 +123,11 @@ class RefreshLinksJob2 extends Job { function run() { global $wgUpdateRowsPerJob; - wfProfileIn( __METHOD__ ); - $linkCache = LinkCache::singleton(); $linkCache->clear(); if ( is_null( $this->title ) ) { $this->error = "refreshLinks2: Invalid title"; - wfProfileOut( __METHOD__ ); return false; } @@ -144,7 +141,7 @@ class RefreshLinksJob2 extends Job { // Hopefully, when leaf jobs are popped, the slaves will have reached that position. if ( isset( $this->params['masterPos'] ) ) { $masterPos = $this->params['masterPos']; - } elseif ( wfGetLB()->getServerCount() > 1 ) { + } elseif ( wfGetLB()->getServerCount() > 1 ) { $masterPos = wfGetLB()->getMasterPos(); } else { $masterPos = false; @@ -158,7 +155,7 @@ class RefreshLinksJob2 extends Job { $jobs = array_merge( $jobs, $this->getSingleTitleJobs( $table, $masterPos ) ); } else { # This is a base job to trigger the insertion of partitioned jobs... - if ( $tbc->getNumLinks( $table ) <= $wgUpdateRowsPerJob ) { + if ( $tbc->getNumLinks( $table, $wgUpdateRowsPerJob + 1 ) <= $wgUpdateRowsPerJob ) { # Just directly insert the single per-title jobs $jobs = array_merge( $jobs, $this->getSingleTitleJobs( $table, $masterPos ) ); } else { @@ -167,10 +164,10 @@ class RefreshLinksJob2 extends Job { list( $start, $end ) = $batch; $jobs[] = new RefreshLinksJob2( $this->title, array( - 'table' => $table, - 'start' => $start, - 'end' => $end, - 'masterPos' => $masterPos, + 'table' => $table, + 'start' => $start, + 'end' => $end, + 'masterPos' => $masterPos, ) + $this->getRootJobParams() // carry over information for de-duplication ); } @@ -181,7 +178,6 @@ class RefreshLinksJob2 extends Job { JobQueueGroup::singleton()->push( $jobs ); } - wfProfileOut( __METHOD__ ); return true; } diff --git a/includes/job/jobs/UploadFromUrlJob.php b/includes/job/jobs/UploadFromUrlJob.php index 87549140..c993cfb4 100644 --- a/includes/job/jobs/UploadFromUrlJob.php +++ b/includes/job/jobs/UploadFromUrlJob.php @@ -48,6 +48,7 @@ class UploadFromUrlJob extends Job { } public function run() { + global $wgCopyUploadAsyncTimeout; # Initialize this object and the upload object $this->upload = new UploadFromUrl(); $this->upload->initialize( @@ -58,7 +59,11 @@ class UploadFromUrlJob extends Job { $this->user = User::newFromName( $this->params['userName'] ); # Fetch the file - $status = $this->upload->fetchFile(); + $opts = array(); + if ( $wgCopyUploadAsyncTimeout ) { + $opts['timeout'] = $wgCopyUploadAsyncTimeout; + } + $status = $this->upload->fetchFile( $opts ); if ( !$status->isOk() ) { $this->leaveMessage( $status ); return true; |