2013-02-06 22:45:33 +00:00
|
|
|
<?php
|
|
|
|
|
|
2018-01-12 21:44:12 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
|
|
|
|
|
2013-02-06 22:45:33 +00:00
|
|
|
/**
|
|
|
|
|
* @group JobQueue
|
|
|
|
|
* @group medium
|
|
|
|
|
* @group Database
|
|
|
|
|
*/
|
|
|
|
|
class JobQueueTest extends MediaWikiTestCase {
|
2013-02-08 18:52:54 +00:00
|
|
|
protected $key;
|
|
|
|
|
protected $queueRand, $queueRandTTL, $queueFifo, $queueFifoTTL;
|
2013-02-06 22:45:33 +00:00
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
function __construct( $name = null, array $data = [], $dataName = '' ) {
|
2013-02-06 22:45:33 +00:00
|
|
|
parent::__construct( $name, $data, $dataName );
|
|
|
|
|
|
|
|
|
|
$this->tablesUsed[] = 'job';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function setUp() {
|
2013-03-21 19:35:44 +00:00
|
|
|
global $wgJobTypeConf;
|
2013-02-06 22:45:33 +00:00
|
|
|
parent::setUp();
|
2013-03-21 19:35:44 +00:00
|
|
|
|
2014-05-05 16:10:07 +00:00
|
|
|
if ( $this->getCliArg( 'use-jobqueue' ) ) {
|
|
|
|
|
$name = $this->getCliArg( 'use-jobqueue' );
|
2013-02-08 18:52:54 +00:00
|
|
|
if ( !isset( $wgJobTypeConf[$name] ) ) {
|
|
|
|
|
throw new MWException( "No \$wgJobTypeConf entry for '$name'." );
|
|
|
|
|
}
|
|
|
|
|
$baseConfig = $wgJobTypeConf[$name];
|
|
|
|
|
} else {
|
2018-01-13 00:02:09 +00:00
|
|
|
$baseConfig = [ 'class' => JobQueueDBSingle::class ];
|
2013-02-08 18:52:54 +00:00
|
|
|
}
|
|
|
|
|
$baseConfig['type'] = 'null';
|
|
|
|
|
$baseConfig['wiki'] = wfWikiID();
|
2016-02-17 09:09:32 +00:00
|
|
|
$variants = [
|
|
|
|
|
'queueRand' => [ 'order' => 'random', 'claimTTL' => 0 ],
|
|
|
|
|
'queueRandTTL' => [ 'order' => 'random', 'claimTTL' => 10 ],
|
|
|
|
|
'queueTimestamp' => [ 'order' => 'timestamp', 'claimTTL' => 0 ],
|
|
|
|
|
'queueTimestampTTL' => [ 'order' => 'timestamp', 'claimTTL' => 10 ],
|
|
|
|
|
'queueFifo' => [ 'order' => 'fifo', 'claimTTL' => 0 ],
|
|
|
|
|
'queueFifoTTL' => [ 'order' => 'fifo', 'claimTTL' => 10 ],
|
|
|
|
|
];
|
2013-03-13 21:26:28 +00:00
|
|
|
foreach ( $variants as $q => $settings ) {
|
|
|
|
|
try {
|
|
|
|
|
$this->$q = JobQueue::factory( $settings + $baseConfig );
|
2013-04-26 12:00:22 +00:00
|
|
|
} catch ( MWException $e ) {
|
2013-05-15 01:12:35 +00:00
|
|
|
// unsupported?
|
|
|
|
|
// @todo What if it was another error?
|
|
|
|
|
};
|
2013-02-08 18:52:54 +00:00
|
|
|
}
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function tearDown() {
|
|
|
|
|
parent::tearDown();
|
2013-03-25 23:27:14 +00:00
|
|
|
foreach (
|
2016-02-17 09:09:32 +00:00
|
|
|
[
|
2013-03-25 23:27:14 +00:00
|
|
|
'queueRand', 'queueRandTTL', 'queueTimestamp', 'queueTimestampTTL',
|
|
|
|
|
'queueFifo', 'queueFifoTTL'
|
2016-02-17 09:09:32 +00:00
|
|
|
] as $q
|
2013-03-25 23:27:14 +00:00
|
|
|
) {
|
2013-03-13 21:26:28 +00:00
|
|
|
if ( $this->$q ) {
|
2013-05-15 02:29:22 +00:00
|
|
|
$this->$q->delete();
|
2013-03-13 21:26:28 +00:00
|
|
|
}
|
|
|
|
|
$this->$q = null;
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provider_queueLists
|
2013-10-24 19:35:04 +00:00
|
|
|
* @covers JobQueue::getWiki
|
2013-02-06 22:45:33 +00:00
|
|
|
*/
|
2013-10-24 19:35:04 +00:00
|
|
|
public function testGetWiki( $queue, $recycles, $desc ) {
|
2013-02-06 22:45:33 +00:00
|
|
|
$queue = $this->$queue;
|
2013-03-13 21:26:28 +00:00
|
|
|
if ( !$queue ) {
|
|
|
|
|
$this->markTestSkipped( $desc );
|
|
|
|
|
}
|
2013-02-06 22:45:33 +00:00
|
|
|
$this->assertEquals( wfWikiID(), $queue->getWiki(), "Proper wiki ID ($desc)" );
|
2013-10-24 19:35:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provider_queueLists
|
|
|
|
|
* @covers JobQueue::getType
|
|
|
|
|
*/
|
|
|
|
|
public function testGetType( $queue, $recycles, $desc ) {
|
|
|
|
|
$queue = $this->$queue;
|
|
|
|
|
if ( !$queue ) {
|
|
|
|
|
$this->markTestSkipped( $desc );
|
|
|
|
|
}
|
2013-02-06 22:45:33 +00:00
|
|
|
$this->assertEquals( 'null', $queue->getType(), "Proper job type ($desc)" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provider_queueLists
|
2013-10-24 19:35:04 +00:00
|
|
|
* @covers JobQueue
|
2013-02-06 22:45:33 +00:00
|
|
|
*/
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testBasicOperations( $queue, $recycles, $desc ) {
|
2013-02-06 22:45:33 +00:00
|
|
|
$queue = $this->$queue;
|
2013-03-13 21:26:28 +00:00
|
|
|
if ( !$queue ) {
|
|
|
|
|
$this->markTestSkipped( $desc );
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-06 22:45:33 +00:00
|
|
|
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
|
|
|
|
|
|
2014-04-16 17:51:11 +00:00
|
|
|
$this->assertNull( $queue->push( $this->newJob() ), "Push worked ($desc)" );
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->assertNull( $queue->batchPush( [ $this->newJob() ] ), "Push worked ($desc)" );
|
2013-02-06 22:45:33 +00:00
|
|
|
|
|
|
|
|
$this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 2, $queue->getSize(), "Queue size is correct ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
|
2013-04-09 21:32:20 +00:00
|
|
|
$jobs = iterator_to_array( $queue->getAllQueuedJobs() );
|
|
|
|
|
$this->assertEquals( 2, count( $jobs ), "Queue iterator size is correct ($desc)" );
|
|
|
|
|
|
2013-02-06 22:45:33 +00:00
|
|
|
$job1 = $queue->pop();
|
|
|
|
|
$this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
if ( $recycles ) {
|
|
|
|
|
$this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$job2 = $queue->pop();
|
|
|
|
|
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
if ( $recycles ) {
|
|
|
|
|
$this->assertEquals( 2, $queue->getAcquiredCount(), "Active job count ($desc)" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$queue->ack( $job1 );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
if ( $recycles ) {
|
|
|
|
|
$this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$queue->ack( $job2 );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
|
2013-05-15 02:29:22 +00:00
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->assertNull( $queue->batchPush( [ $this->newJob(), $this->newJob() ] ),
|
2013-05-15 02:29:22 +00:00
|
|
|
"Push worked ($desc)" );
|
|
|
|
|
$this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->delete();
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provider_queueLists
|
2013-10-24 19:35:04 +00:00
|
|
|
* @covers JobQueue
|
2013-02-06 22:45:33 +00:00
|
|
|
*/
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testBasicDeduplication( $queue, $recycles, $desc ) {
|
2013-02-06 22:45:33 +00:00
|
|
|
$queue = $this->$queue;
|
2013-03-13 21:26:28 +00:00
|
|
|
if ( !$queue ) {
|
|
|
|
|
$this->markTestSkipped( $desc );
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-06 22:45:33 +00:00
|
|
|
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
|
|
|
|
|
|
2014-04-16 17:51:11 +00:00
|
|
|
$this->assertNull(
|
2013-03-25 23:27:14 +00:00
|
|
|
$queue->batchPush(
|
2016-02-17 09:09:32 +00:00
|
|
|
[ $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ]
|
2013-03-25 23:27:14 +00:00
|
|
|
),
|
2013-02-06 22:45:33 +00:00
|
|
|
"Push worked ($desc)" );
|
|
|
|
|
|
|
|
|
|
$this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
|
|
|
|
|
|
2014-04-16 17:51:11 +00:00
|
|
|
$this->assertNull(
|
2013-03-25 23:27:14 +00:00
|
|
|
$queue->batchPush(
|
2016-02-17 09:09:32 +00:00
|
|
|
[ $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ]
|
2013-03-25 23:27:14 +00:00
|
|
|
),
|
|
|
|
|
"Push worked ($desc)"
|
|
|
|
|
);
|
2013-02-06 22:45:33 +00:00
|
|
|
|
|
|
|
|
$this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
|
|
|
|
|
|
|
|
|
|
$job1 = $queue->pop();
|
|
|
|
|
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
|
|
|
|
|
if ( $recycles ) {
|
|
|
|
|
$this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$queue->ack( $job1 );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provider_queueLists
|
2013-10-24 19:35:04 +00:00
|
|
|
* @covers JobQueue
|
2015-11-10 05:24:34 +00:00
|
|
|
*/
|
|
|
|
|
public function testDeduplicationWhileClaimed( $queue, $recycles, $desc ) {
|
|
|
|
|
$queue = $this->$queue;
|
|
|
|
|
if ( !$queue ) {
|
|
|
|
|
$this->markTestSkipped( $desc );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$job = $this->newDedupedJob();
|
|
|
|
|
$queue->push( $job );
|
|
|
|
|
|
|
|
|
|
// De-duplication does not apply to already-claimed jobs
|
|
|
|
|
$j = $queue->pop();
|
|
|
|
|
$queue->push( $job );
|
|
|
|
|
$queue->ack( $j );
|
|
|
|
|
|
|
|
|
|
$j = $queue->pop();
|
|
|
|
|
// Make sure ack() of the twin did not delete the sibling data
|
2018-01-13 00:02:09 +00:00
|
|
|
$this->assertType( NullJob::class, $j );
|
2015-11-10 05:24:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provider_queueLists
|
|
|
|
|
* @covers JobQueue
|
2013-02-06 22:45:33 +00:00
|
|
|
*/
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testRootDeduplication( $queue, $recycles, $desc ) {
|
2013-02-06 22:45:33 +00:00
|
|
|
$queue = $this->$queue;
|
2013-03-13 21:26:28 +00:00
|
|
|
if ( !$queue ) {
|
|
|
|
|
$this->markTestSkipped( $desc );
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-06 22:45:33 +00:00
|
|
|
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$id = wfRandomString( 32 );
|
|
|
|
|
$root1 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp
|
2013-02-15 10:17:52 +00:00
|
|
|
for ( $i = 0; $i < 5; ++$i ) {
|
2014-04-16 17:51:11 +00:00
|
|
|
$this->assertNull( $queue->push( $this->newJob( 0, $root1 ) ), "Push worked ($desc)" );
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
$queue->deduplicateRootJob( $this->newJob( 0, $root1 ) );
|
2014-10-22 21:22:10 +00:00
|
|
|
|
|
|
|
|
$root2 = $root1;
|
|
|
|
|
# Add a second to UNIX epoch and format back to TS_MW
|
|
|
|
|
$root2_ts = strtotime( $root2['rootJobTimestamp'] );
|
|
|
|
|
$root2_ts++;
|
|
|
|
|
$root2['rootJobTimestamp'] = wfTimestamp( TS_MW, $root2_ts );
|
|
|
|
|
|
2013-02-06 22:45:33 +00:00
|
|
|
$this->assertNotEquals( $root1['rootJobTimestamp'], $root2['rootJobTimestamp'],
|
|
|
|
|
"Root job signatures have different timestamps." );
|
2013-02-15 10:17:52 +00:00
|
|
|
for ( $i = 0; $i < 5; ++$i ) {
|
2014-04-16 17:51:11 +00:00
|
|
|
$this->assertNull( $queue->push( $this->newJob( 0, $root2 ) ), "Push worked ($desc)" );
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
$queue->deduplicateRootJob( $this->newJob( 0, $root2 ) );
|
|
|
|
|
|
|
|
|
|
$this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 10, $queue->getSize(), "Queue size is correct ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
|
|
|
|
|
|
|
|
|
|
$dupcount = 0;
|
2016-02-17 09:09:32 +00:00
|
|
|
$jobs = [];
|
2013-02-06 22:45:33 +00:00
|
|
|
do {
|
|
|
|
|
$job = $queue->pop();
|
|
|
|
|
if ( $job ) {
|
|
|
|
|
$jobs[] = $job;
|
|
|
|
|
$queue->ack( $job );
|
|
|
|
|
}
|
2013-02-15 10:17:52 +00:00
|
|
|
if ( $job instanceof DuplicateJob ) {
|
|
|
|
|
++$dupcount;
|
|
|
|
|
}
|
2013-02-06 22:45:33 +00:00
|
|
|
} while ( $job );
|
|
|
|
|
|
|
|
|
|
$this->assertEquals( 10, count( $jobs ), "Correct number of jobs popped ($desc)" );
|
|
|
|
|
$this->assertEquals( 5, $dupcount, "Correct number of duplicate jobs popped ($desc)" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provider_fifoQueueLists
|
2013-10-24 19:35:04 +00:00
|
|
|
* @covers JobQueue
|
2013-02-06 22:45:33 +00:00
|
|
|
*/
|
2013-10-23 22:51:31 +00:00
|
|
|
public function testJobOrder( $queue, $recycles, $desc ) {
|
2013-02-06 22:45:33 +00:00
|
|
|
$queue = $this->$queue;
|
2013-03-13 21:26:28 +00:00
|
|
|
if ( !$queue ) {
|
|
|
|
|
$this->markTestSkipped( $desc );
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-06 22:45:33 +00:00
|
|
|
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
|
|
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
|
|
|
|
|
|
2013-02-15 10:17:52 +00:00
|
|
|
for ( $i = 0; $i < 10; ++$i ) {
|
2014-04-16 17:51:11 +00:00
|
|
|
$this->assertNull( $queue->push( $this->newJob( $i ) ), "Push worked ($desc)" );
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
2013-02-15 10:17:52 +00:00
|
|
|
for ( $i = 0; $i < 10; ++$i ) {
|
2013-02-06 22:45:33 +00:00
|
|
|
$job = $queue->pop();
|
|
|
|
|
$this->assertTrue( $job instanceof Job, "Jobs popped from queue ($desc)" );
|
|
|
|
|
$params = $job->getParams();
|
|
|
|
|
$this->assertEquals( $i, $params['i'], "Job popped from queue is FIFO ($desc)" );
|
|
|
|
|
$queue->ack( $job );
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-08 18:52:54 +00:00
|
|
|
$this->assertFalse( $queue->pop(), "Queue is not empty ($desc)" );
|
2013-02-06 22:45:33 +00:00
|
|
|
|
|
|
|
|
$queue->flushCaches();
|
|
|
|
|
$this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
|
|
|
|
|
$this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-12 00:10:29 +00:00
|
|
|
/**
|
|
|
|
|
* @covers JobQueue
|
|
|
|
|
*/
|
|
|
|
|
public function testQueueAggregateTable() {
|
|
|
|
|
$queue = $this->queueFifo;
|
|
|
|
|
if ( !$queue || !method_exists( $queue, 'getServerQueuesWithJobs' ) ) {
|
|
|
|
|
$this->markTestSkipped();
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-11 01:13:48 +00:00
|
|
|
$this->assertNotContains(
|
2016-02-17 09:09:32 +00:00
|
|
|
[ $queue->getType(), $queue->getWiki() ],
|
2015-12-11 01:13:48 +00:00
|
|
|
$queue->getServerQueuesWithJobs(),
|
|
|
|
|
"Null queue not in listing"
|
|
|
|
|
);
|
2015-11-12 00:10:29 +00:00
|
|
|
|
|
|
|
|
$queue->push( $this->newJob( 0 ) );
|
|
|
|
|
|
2015-12-11 01:13:48 +00:00
|
|
|
$this->assertContains(
|
2016-02-17 09:09:32 +00:00
|
|
|
[ $queue->getType(), $queue->getWiki() ],
|
2015-12-11 01:13:48 +00:00
|
|
|
$queue->getServerQueuesWithJobs(),
|
|
|
|
|
"Null queue in listing"
|
2015-11-12 00:10:29 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-22 02:12:37 +00:00
|
|
|
public static function provider_queueLists() {
|
2016-02-17 09:09:32 +00:00
|
|
|
return [
|
|
|
|
|
[ 'queueRand', false, 'Random queue without ack()' ],
|
|
|
|
|
[ 'queueRandTTL', true, 'Random queue with ack()' ],
|
|
|
|
|
[ 'queueTimestamp', false, 'Time ordered queue without ack()' ],
|
|
|
|
|
[ 'queueTimestampTTL', true, 'Time ordered queue with ack()' ],
|
|
|
|
|
[ 'queueFifo', false, 'FIFO ordered queue without ack()' ],
|
|
|
|
|
[ 'queueFifoTTL', true, 'FIFO ordered queue with ack()' ]
|
|
|
|
|
];
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-22 02:12:37 +00:00
|
|
|
public static function provider_fifoQueueLists() {
|
2016-02-17 09:09:32 +00:00
|
|
|
return [
|
|
|
|
|
[ 'queueFifo', false, 'Ordered queue without ack()' ],
|
|
|
|
|
[ 'queueFifoTTL', true, 'Ordered queue with ack()' ]
|
|
|
|
|
];
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
function newJob( $i = 0, $rootJob = [] ) {
|
2013-02-06 22:45:33 +00:00
|
|
|
return new NullJob( Title::newMainPage(),
|
2016-02-17 09:09:32 +00:00
|
|
|
[ 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 0, 'i' => $i ] + $rootJob );
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
function newDedupedJob( $i = 0, $rootJob = [] ) {
|
2013-02-06 22:45:33 +00:00
|
|
|
return new NullJob( Title::newMainPage(),
|
2016-02-17 09:09:32 +00:00
|
|
|
[ 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 1, 'i' => $i ] + $rootJob );
|
2013-02-06 22:45:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
2018-01-12 21:44:12 +00:00
|
|
|
|
|
|
|
|
class JobQueueDBSingle extends JobQueueDB {
|
|
|
|
|
protected function getDB( $index ) {
|
|
|
|
|
$lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
|
2018-04-04 23:29:18 +00:00
|
|
|
// Override to not use CONN_TRX_AUTOCOMMIT so that we see the same temporary `job` table
|
2018-01-12 21:44:12 +00:00
|
|
|
return $lb->getConnection( $index, [], $this->wiki );
|
|
|
|
|
}
|
|
|
|
|
}
|