summaryrefslogtreecommitdiff
path: root/includes/job/jobs
diff options
context:
space:
mode:
Diffstat (limited to 'includes/job/jobs')
-rw-r--r--includes/job/jobs/AssembleUploadChunksJob.php19
-rw-r--r--includes/job/jobs/DoubleRedirectJob.php29
-rw-r--r--includes/job/jobs/DuplicateJob.php2
-rw-r--r--includes/job/jobs/EnotifNotifyJob.php2
-rw-r--r--includes/job/jobs/HTMLCacheUpdateJob.php25
-rw-r--r--includes/job/jobs/NullJob.php16
-rw-r--r--includes/job/jobs/PublishStashedFileJob.php22
-rw-r--r--includes/job/jobs/RefreshLinksJob.php28
-rw-r--r--includes/job/jobs/UploadFromUrlJob.php7
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;