MediaWiki
REL1_23
|
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 } while ( $again ); 00082 00083 if ( $this->hasOption( 'types' ) ) { 00084 $this->output( $db . " " . $type . "\n" ); 00085 } else { 00086 $this->output( $db . "\n" ); 00087 } 00088 } 00089 00094 private function executeReadyPeriodicTasks() { 00095 global $wgLocalDatabases, $wgMemc; 00096 00097 $count = 0; 00098 $memcKey = 'jobqueue:periodic:lasttime'; 00099 $timestamp = (int)$wgMemc->get( $memcKey ); // UNIX timestamp or 0 00100 if ( ( time() - $timestamp ) > 300 || mt_rand( 0, 999 ) == 0 ) { // 5 minutes 00101 if ( $wgMemc->add( "$memcKey:rebuild", 1, 1800 ) ) { // lock 00102 foreach ( $wgLocalDatabases as $db ) { 00103 $count += JobQueueGroup::singleton( $db )->executeReadyPeriodicTasks(); 00104 } 00105 $wgMemc->set( $memcKey, time() ); 00106 $wgMemc->delete( "$memcKey:rebuild" ); // unlock 00107 } 00108 } 00109 00110 return $count; 00111 } 00112 } 00113 00114 $maintClass = "NextJobDb"; 00115 require_once RUN_MAINTENANCE_IF_MAIN;