From 3592f8cea3710fd6f284c5b07625e588edbab0d0 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Tue, 12 Jan 2016 21:51:09 -0800 Subject: [PATCH] Add simple JobQueueMemory class for testing Change-Id: I1acce43dbab3b12393d6dc4675850695c619d88a --- autoload.php | 1 + includes/jobqueue/JobQueueMemory.php | 169 +++++++++++++++++++++++++++ tests/phpunit/phpunit.php | 5 + 3 files changed, 175 insertions(+) create mode 100644 includes/jobqueue/JobQueueMemory.php diff --git a/autoload.php b/autoload.php index 7fde81c18c..7dec6b7a35 100644 --- a/autoload.php +++ b/autoload.php @@ -611,6 +611,7 @@ $wgAutoloadLocalClasses = array( 'JobQueueError' => __DIR__ . '/includes/jobqueue/JobQueue.php', 'JobQueueFederated' => __DIR__ . '/includes/jobqueue/JobQueueFederated.php', 'JobQueueGroup' => __DIR__ . '/includes/jobqueue/JobQueueGroup.php', + 'JobQueueMemory' => __DIR__ . '/includes/jobqueue/JobQueueMemory.php', 'JobQueueRedis' => __DIR__ . '/includes/jobqueue/JobQueueRedis.php', 'JobRunner' => __DIR__ . '/includes/jobqueue/JobRunner.php', 'JobSpecification' => __DIR__ . '/includes/jobqueue/JobSpecification.php', diff --git a/includes/jobqueue/JobQueueMemory.php b/includes/jobqueue/JobQueueMemory.php new file mode 100644 index 0000000000..c5d7257468 --- /dev/null +++ b/includes/jobqueue/JobQueueMemory.php @@ -0,0 +1,169 @@ +getQueueData( 'unclaimed', array() ); + + /** @var IJobSpecification[] $jobs */ + foreach ( $jobs as $job ) { + if ( $job->ignoreDuplicates() ) { + $sha1 = Wikimedia\base_convert( + sha1( serialize( $job->getDeduplicationInfo() ) ), + 16, 36, 31 + ); + if ( !isset( $unclaimed[$sha1] ) ) { + $unclaimed[$sha1] = $job; + } + } else { + $unclaimed[] = $job; + } + } + } + + protected function supportedOrders() { + return array( 'random', 'timestamp', 'fifo' ); + } + + protected function optimalOrder() { + return array( 'fifo' ); + } + + protected function doIsEmpty() { + return ( $this->doGetSize() == 0 ); + } + + protected function doGetSize() { + $unclaimed = $this->getQueueData( 'unclaimed' ); + + return $unclaimed ? count( $unclaimed ) : 0; + } + + protected function doGetAcquiredCount() { + $claimed = $this->getQueueData( 'claimed' ); + + return $claimed ? count( $claimed ) : 0; + } + + protected function doPop() { + if ( $this->doGetSize() == 0 ) { + return false; + } + + $unclaimed =& $this->getQueueData( 'unclaimed' ); + $claimed =& $this->getQueueData( 'claimed', array() ); + + if ( $this->order === 'random' ) { + $key = array_rand( $unclaimed ); + } else { + reset( $unclaimed ); + $key = key( $unclaimed ); + } + + $spec = $unclaimed[$key]; + unset( $unclaimed[$key] ); + $claimed[] = $spec; + + $job = $this->jobFromSpecInternal( $spec ); + + end( $claimed ); + $job->metadata['claimId'] = key( $claimed ); + + return $job; + } + + protected function doAck( Job $job ) { + if ( $this->getAcquiredCount() == 0 ) { + return; + } + + $claimed =& $this->getQueueData( 'claimed' ); + unset( $claimed[$job->metadata['claimId']] ); + } + + protected function doDelete() { + if ( isset( self::$data[$this->type][$this->wiki] ) ) { + unset( self::$data[$this->type][$this->wiki] ); + if ( !self::$data[$this->type] ) { + unset( self::$data[$this->type] ); + } + } + } + + public function getAllQueuedJobs() { + $unclaimed = $this->getQueueData( 'unclaimed' ); + if ( !$unclaimed ) { + return new ArrayIterator( array() ); + } + + $that = $this; + return new MappedIterator( + $unclaimed, + function ( $value ) use ( $that ) { + $that->jobFromSpecInternal( $value ); + } + ); + } + + public function getAllAcquiredJobs() { + $claimed = $this->getQueueData( 'claimed' ); + if ( !$claimed ) { + return new ArrayIterator( array() ); + } + + $that = $this; + return new MappedIterator( + $claimed, + function ( $value ) use ( $that ) { + $that->jobFromSpecInternal( $value ); + } + ); + } + + public function jobFromSpecInternal( IJobSpecification $spec ) { + return Job::factory( $spec->getType(), $spec->getTitle(), $spec->getParams() ); + } + + private function &getQueueData( $field, $init = null ) { + if ( !isset( self::$data[$this->type][$this->wiki][$field] ) ) { + if ( $init !== null ) { + self::$data[$this->type][$this->wiki][$field] = $init; + } else { + return null; + } + } + + return self::$data[$this->type][$this->wiki][$field]; + } +} diff --git a/tests/phpunit/phpunit.php b/tests/phpunit/phpunit.php index ee0358c128..0ae0b21385 100755 --- a/tests/phpunit/phpunit.php +++ b/tests/phpunit/phpunit.php @@ -75,6 +75,7 @@ class PHPUnitMaintClass extends Maintenance { global $wgLocaltimezone, $wgLocalisationCacheConf; global $wgDevelopmentWarnings; global $wgSessionProviders; + global $wgJobTypeConf; // Inject test autoloader require_once __DIR__ . '/../TestsAutoLoader.php'; @@ -97,6 +98,10 @@ class PHPUnitMaintClass extends Maintenance { $wgLanguageConverterCacheType = 'hash'; // Uses db-replicated in DefaultSettings $wgMainStash = 'hash'; + // Use memory job queue + $wgJobTypeConf = array( + 'default' => array( 'class' => 'JobQueueMemory', 'order' => 'fifo' ), + ); $wgUseDatabaseMessages = false; # Set for future resets -- 2.20.1