MediaWiki  REL1_21
nextJobDB.php
Go to the documentation of this file.
00001 <?php
00024 require_once( __DIR__ . '/Maintenance.php' );
00025 
00031 class nextJobDB extends Maintenance {
00032         public function __construct() {
00033                 parent::__construct();
00034                 $this->mDescription = "Pick a database that has pending jobs";
00035                 $this->addOption( 'type', "Search by job type", false, true );
00036                 $this->addOption( 'types', "Space separated list of job types to search for", false, true );
00037         }
00038 
00039         public function execute() {
00040                 global $wgJobTypesExcludedFromDefaultQueue;
00041 
00042                 // job type required/picked
00043                 if ( $this->hasOption( 'types' ) ) {
00044                         $types = explode( ' ', $this->getOption( 'types' ) );
00045                 } elseif ( $this->hasOption( 'type' ) ) {
00046                         $types = array( $this->getOption( 'type' ) );
00047                 } else {
00048                         $types = false;
00049                 }
00050 
00051                 // Handle any required periodic queue maintenance
00052                 $this->executeReadyPeriodicTasks();
00053 
00054                 // Get all the queues with jobs in them
00055                 $pendingDBs = JobQueueAggregator::singleton()->getAllReadyWikiQueues();
00056                 if ( !count( $pendingDBs ) ) {
00057                         return; // no DBs with jobs or cache is both empty and locked
00058                 }
00059 
00060                 do {
00061                         $again = false;
00062 
00063                         $candidates = array(); // list of (type, db)
00064                         // Flatten the tree of candidates into a flat list so that a random
00065                         // item can be selected, weighing each queue (type/db tuple) equally.
00066                         foreach ( $pendingDBs as $type => $dbs ) {
00067                                 if (
00068                                         ( is_array( $types ) && in_array( $type, $types ) ) ||
00069                                         ( $types === false && !in_array( $type, $wgJobTypesExcludedFromDefaultQueue ) )
00070                                 ) {
00071                                         foreach ( $dbs as $db ) {
00072                                                 $candidates[] = array( $type, $db );
00073                                         }
00074                                 }
00075                         }
00076                         if ( !count( $candidates ) ) {
00077                                 return; // no jobs for this type
00078                         }
00079 
00080                         list( $type, $db ) = $candidates[mt_rand( 0, count( $candidates ) - 1 )];
00081                         if ( JobQueueGroup::singleton( $db )->isQueueDeprioritized( $type ) ) {
00082                                 $pendingDBs[$type] = array_diff( $pendingDBs[$type], array( $db ) );
00083                                 $again = true;
00084                         }
00085                 } while ( $again );
00086 
00087                 if ( $this->hasOption( 'types' ) ) {
00088                         $this->output( $db . " " . $type . "\n" );
00089                 } else {
00090                         $this->output( $db . "\n" );
00091                 }
00092         }
00093 
00098         private function executeReadyPeriodicTasks() {
00099                 global $wgLocalDatabases, $wgMemc;
00100 
00101                 $count = 0;
00102                 $memcKey = 'jobqueue:periodic:lasttime';
00103                 $timestamp = (int)$wgMemc->get( $memcKey ); // UNIX timestamp or 0
00104                 if ( ( time() - $timestamp ) > 300 || mt_rand( 0, 999 ) == 0 ) { // 5 minutes
00105                         if ( $wgMemc->add( "$memcKey:rebuild", 1, 1800 ) ) { // lock
00106                                 foreach ( $wgLocalDatabases as $db ) {
00107                                         $count += JobQueueGroup::singleton( $db )->executeReadyPeriodicTasks();
00108                                 }
00109                                 $wgMemc->set( $memcKey, time() );
00110                                 $wgMemc->delete( "$memcKey:rebuild" ); // unlock
00111                         }
00112                 }
00113 
00114                 return $count;
00115         }
00116 }
00117 
00118 $maintClass = "nextJobDb";
00119 require_once( RUN_MAINTENANCE_IF_MAIN );