From e2826974c69f4a0b9b76944c4108a9af4013150b Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Sat, 23 May 2015 10:53:12 -0700 Subject: [PATCH] Automatically deduplicate root jobs on insertion * This makes lazyPush() simple to use in more cases Change-Id: I22e74485eaf3120e5669c5ee55dc7ab7310d7300 --- includes/deferred/HTMLCacheUpdate.php | 1 - includes/deferred/LinksUpdate.php | 1 - includes/jobqueue/Job.php | 20 ++++++++++++++++++++ includes/jobqueue/JobQueue.php | 6 ++++++ includes/jobqueue/JobSpecification.php | 10 ++++++++++ 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/includes/deferred/HTMLCacheUpdate.php b/includes/deferred/HTMLCacheUpdate.php index 20e4a4c680..a480aec83a 100644 --- a/includes/deferred/HTMLCacheUpdate.php +++ b/includes/deferred/HTMLCacheUpdate.php @@ -56,7 +56,6 @@ class HTMLCacheUpdate implements DeferrableUpdate { $count = $this->mTitle->getBacklinkCache()->getNumLinks( $this->mTable, 100 ); if ( $count >= 100 ) { // many backlinks JobQueueGroup::singleton()->lazyPush( $job ); - JobQueueGroup::singleton()->deduplicateRootJob( $job ); } else { // few backlinks ($count might be off even if 0) $dbw = wfGetDB( DB_MASTER ); $dbw->onTransactionIdle( function () use ( $job ) { diff --git a/includes/deferred/LinksUpdate.php b/includes/deferred/LinksUpdate.php index e4f00e7544..eeadd16451 100644 --- a/includes/deferred/LinksUpdate.php +++ b/includes/deferred/LinksUpdate.php @@ -267,7 +267,6 @@ class LinksUpdate extends SqlDataUpdate { ); JobQueueGroup::singleton()->push( $job ); - JobQueueGroup::singleton()->deduplicateRootJob( $job ); } } diff --git a/includes/jobqueue/Job.php b/includes/jobqueue/Job.php index 87bd836d16..78e1f710e4 100644 --- a/includes/jobqueue/Job.php +++ b/includes/jobqueue/Job.php @@ -196,15 +196,27 @@ abstract class Job implements IJobSpecification { } /** + * Get "root job" parameters for a task + * + * This is used to no-op redundant jobs, including child jobs of jobs, + * as long as the children inherit the root job parameters. When a job + * with root job parameters and "rootJobIsSelf" set is pushed, the + * deduplicateRootJob() method is automatically called on it. If the + * root job is only virtual and not actually pushed (e.g. the sub-jobs + * are inserted directly), then call deduplicateRootJob() directly. + * * @see JobQueue::deduplicateRootJob() + * * @param string $key A key that identifies the task * @return array Map of: + * - rootJobIsSelf : true * - rootJobSignature : hash (e.g. SHA1) that identifies the task * - rootJobTimestamp : TS_MW timestamp of this instance of the task * @since 1.21 */ public static function newRootJobParams( $key ) { return array( + 'rootJobIsSelf' => true, 'rootJobSignature' => sha1( $key ), 'rootJobTimestamp' => wfTimestampNow() ); @@ -236,6 +248,14 @@ abstract class Job implements IJobSpecification { && isset( $this->params['rootJobTimestamp'] ); } + /** + * @see JobQueue::deduplicateRootJob() + * @return bool Whether this is job is a root job + */ + public function isRootJob() { + return $this->hasRootJobParams() && !empty( $this->params['rootJobIsSelf'] ); + } + /** * Insert a single job into the queue. * @return bool True on success diff --git a/includes/jobqueue/JobQueue.php b/includes/jobqueue/JobQueue.php index 1a68489924..013cc61bf5 100644 --- a/includes/jobqueue/JobQueue.php +++ b/includes/jobqueue/JobQueue.php @@ -323,6 +323,12 @@ abstract class JobQueue { $this->doBatchPush( $jobs, $flags ); $this->aggr->notifyQueueNonEmpty( $this->wiki, $this->type ); + + foreach ( $jobs as $job ) { + if ( $job->isRootJob() ) { + $this->deduplicateRootJob( $job ); + } + } } /** diff --git a/includes/jobqueue/JobSpecification.php b/includes/jobqueue/JobSpecification.php index ecace3a3ee..d59c09b510 100644 --- a/includes/jobqueue/JobSpecification.php +++ b/includes/jobqueue/JobSpecification.php @@ -72,6 +72,12 @@ interface IJobSpecification { */ public function hasRootJobParams(); + /** + * @see JobQueue::deduplicateRootJob() + * @return bool Whether this is job is a root job + */ + public function isRootJob(); + /** * @return Title Descriptive title (this can simply be informative) */ @@ -195,6 +201,10 @@ class JobSpecification implements IJobSpecification { && isset( $this->params['rootJobTimestamp'] ); } + public function isRootJob() { + return $this->hasRootJobParams() && !empty( $this->params['rootJobIsSelf'] ); + } + /** * @return array Field/value map that can immediately be serialized * @since 1.25 -- 2.20.1