From bdd03c513c268257f2c1de4cf335f0640286434a Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Wed, 20 Mar 2013 12:40:09 -0700 Subject: [PATCH] [JobQueue] Added JobQueue::getAbandonedCount() and use it in showJobs.php. Change-Id: I5d96c61165b2693589d5cf36309fdb6a8b5a137e --- includes/job/JobQueue.php | 24 ++++++++++++++++++++++++ includes/job/JobQueueDB.php | 33 +++++++++++++++++++++++++++++++++ includes/job/JobQueueRedis.php | 17 +++++++++++++++++ maintenance/showJobs.php | 7 ++++++- 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/includes/job/JobQueue.php b/includes/job/JobQueue.php index 09ca67c345..41ef4432d4 100644 --- a/includes/job/JobQueue.php +++ b/includes/job/JobQueue.php @@ -238,6 +238,30 @@ abstract class JobQueue { return 0; // not implemented } + /** + * Get the number of acquired jobs that can no longer be attempted. + * Queue classes should use caching if they are any slower without memcached. + * + * If caching is used, this number might be out of date for a minute. + * + * @return integer + * @throws MWException + */ + final public function getAbandonedCount() { + wfProfileIn( __METHOD__ ); + $res = $this->doGetAbandonedCount(); + wfProfileOut( __METHOD__ ); + return $res; + } + + /** + * @see JobQueue::getAbandonedCount() + * @return integer + */ + protected function doGetAbandonedCount() { + return 0; // not implemented + } + /** * Push a single jobs into the queue. * This does not require $wgJobClasses to be set for the given job type. diff --git a/includes/job/JobQueueDB.php b/includes/job/JobQueueDB.php index d6e96ef3ed..ae4576c8a6 100644 --- a/includes/job/JobQueueDB.php +++ b/includes/job/JobQueueDB.php @@ -136,6 +136,39 @@ class JobQueueDB extends JobQueue { return $count; } + /** + * @see JobQueue::doGetAbandonedCount() + * @return integer + * @throws MWException + */ + protected function doGetAbandonedCount() { + global $wgMemc; + + if ( $this->claimTTL <= 0 ) { + return 0; // no acknowledgements + } + + $key = $this->getCacheKey( 'abandonedcount' ); + + $count = $wgMemc->get( $key ); + if ( is_int( $count ) ) { + return $count; + } + + list( $dbr, $scope ) = $this->getSlaveDB(); + $count = (int)$dbr->selectField( 'job', 'COUNT(*)', + array( + 'job_cmd' => $this->type, + "job_token != {$dbr->addQuotes( '' )}", + "job_attempts >= " . $dbr->addQuotes( $this->maxTries ) + ), + __METHOD__ + ); + $wgMemc->set( $key, $count, self::CACHE_TTL_SHORT ); + + return $count; + } + /** * @see JobQueue::doBatchPush() * @param array $jobs diff --git a/includes/job/JobQueueRedis.php b/includes/job/JobQueueRedis.php index 706d42d595..d0901ef62e 100644 --- a/includes/job/JobQueueRedis.php +++ b/includes/job/JobQueueRedis.php @@ -154,6 +154,23 @@ class JobQueueRedis extends JobQueue { } } + /** + * @see JobQueue::doGetAbandonedCount() + * @return integer + * @throws MWException + */ + protected function doGetAbandonedCount() { + if ( $this->claimTTL <= 0 ) { + return 0; // no acknowledgements + } + $conn = $this->getConnection(); + try { + return $conn->zSize( $this->getQueueKey( 'z-abandoned' ) ); + } catch ( RedisException $e ) { + $this->throwRedisException( $this->server, $conn, $e ); + } + } + /** * @see JobQueue::doBatchPush() * @param array $jobs diff --git a/maintenance/showJobs.php b/maintenance/showJobs.php index 8b49517ff8..831746d607 100644 --- a/maintenance/showJobs.php +++ b/maintenance/showJobs.php @@ -47,8 +47,13 @@ class ShowJobs extends Maintenance { $queue = $group->get( $type ); $pending = $queue->getSize(); $claimed = $queue->getAcquiredCount(); + $abandoned = $queue->getAbandonedCount(); + $active = ( $claimed - $abandoned ); if ( ( $pending + $claimed ) > 0 ) { - $this->output( "{$type}: $pending queued; $claimed acquired\n" ); + $this->output( + "{$type}: $pending queued; " . + "$claimed claimed ($active active, $abandoned abandoned)\n" + ); } } } else { -- 2.20.1