Some more editor files to ignore.
[lhc/web/wiklou.git] / maintenance / nextJobDB.php
index 032d6f9..1be5146 100644 (file)
@@ -37,48 +37,26 @@ class nextJobDB extends Maintenance {
        }
 
        public function execute() {
-               global $wgMemc;
+               global $wgJobTypesExcludedFromDefaultQueue;
 
-               $type = false; // job type required/picked
+               // job type required/picked
                if ( $this->hasOption( 'types' ) ) {
                        $types = explode( ' ', $this->getOption( 'types' ) );
                } elseif ( $this->hasOption( 'type' ) ) {
                        $types = array( $this->getOption( 'type' ) );
                } else {
-                       $types = JobQueueGroup::singleton()->getDefaultQueueTypes();
+                       $types = false;
                }
 
-               $memcKey = 'jobqueue:dbs:v3';
-               $pendingDbInfo = $wgMemc->get( $memcKey );
+               // Handle any required periodic queue maintenance
+               $this->executeReadyPeriodicTasks();
 
-               // If the cache entry wasn't present, is stale, or in .1% of cases otherwise,
-               // regenerate the cache. Use any available stale cache if another process is
-               // currently regenerating the pending DB information.
-               if ( !is_array( $pendingDbInfo )
-                       || ( time() - $pendingDbInfo['timestamp'] ) > 300 // 5 minutes
-                       || mt_rand( 0, 999 ) == 0
-               ) {
-                       if ( $wgMemc->add( "$memcKey:rebuild", 1, 1800 ) ) { // lock
-                               $pendingDbInfo = array(
-                                       'pendingDBs' => $this->getPendingDbs(),
-                                       'timestamp'  => time()
-                               );
-                               for ( $attempts=1; $attempts <= 25; ++$attempts ) {
-                                       if ( $wgMemc->add( "$memcKey:lock", 1, 60 ) ) { // lock
-                                               $wgMemc->set( $memcKey, $pendingDbInfo );
-                                               $wgMemc->delete( "$memcKey:lock" ); // unlock
-                                               break;
-                                       }
-                               }
-                               $wgMemc->delete( "$memcKey:rebuild" ); // unlock
-                       }
-               }
-
-               if ( !is_array( $pendingDbInfo ) || !$pendingDbInfo['pendingDBs'] ) {
+               // Get all the queues with jobs in them
+               $pendingDBs = JobQueueAggregator::singleton()->getAllReadyWikiQueues();
+               if ( !count( $pendingDBs ) ) {
                        return; // no DBs with jobs or cache is both empty and locked
                }
 
-               $pendingDBs = $pendingDbInfo['pendingDBs']; // convenience
                do {
                        $again = false;
 
@@ -86,7 +64,10 @@ class nextJobDB extends Maintenance {
                        // Flatten the tree of candidates into a flat list so that a random
                        // item can be selected, weighing each queue (type/db tuple) equally.
                        foreach ( $pendingDBs as $type => $dbs ) {
-                               if ( in_array( $type, $types ) ) {
+                               if (
+                                       ( is_array( $types ) && in_array( $type, $types ) ) ||
+                                       ( $types === false && !in_array( $type, $wgJobTypesExcludedFromDefaultQueue ) )
+                               ) {
                                        foreach ( $dbs as $db ) {
                                                $candidates[] = array( $type, $db );
                                        }
@@ -96,22 +77,9 @@ class nextJobDB extends Maintenance {
                                return; // no jobs for this type
                        }
 
-                       list( $type, $db ) = $candidates[ mt_rand( 0, count( $candidates ) - 1 ) ];
-                       if ( !$this->checkJob( $type, $db ) ) { // queue is actually empty?
-                               $pendingDBs = $this->delistDB( $pendingDBs, $db, $type );
-                               // Update the cache to remove the outdated information.
-                               // Make sure that this does not race (especially with full rebuilds).
-                               if ( $wgMemc->add( "$memcKey:lock", 1, 60 ) ) { // lock
-                                       $curInfo = $wgMemc->get( $memcKey );
-                                       if ( is_array( $curInfo ) ) {
-                                               $curInfo['pendingDBs'] =
-                                                       $this->delistDB( $curInfo['pendingDBs'], $db, $type );
-                                               $wgMemc->set( $memcKey, $curInfo );
-                                               // May as well make use of this newer information
-                                               $pendingDBs = $curInfo['pendingDBs'];
-                                       }
-                                       $wgMemc->delete( "$memcKey:lock" ); // unlock
-                               }
+                       list( $type, $db ) = $candidates[mt_rand( 0, count( $candidates ) - 1 )];
+                       if ( JobQueueGroup::singleton( $db )->isQueueDeprioritized( $type ) ) {
+                               $pendingDBs[$type] = array_diff( $pendingDBs[$type], array( $db ) );
                                $again = true;
                        }
                } while ( $again );
@@ -124,45 +92,26 @@ class nextJobDB extends Maintenance {
        }
 
        /**
-        * Remove a type/DB entry from the list of queues with jobs
-        *
-        * @param $pendingDBs array
-        * @param $db string
-        * @param $type string
-        * @return Array
-        */
-       private function delistDB( array $pendingDBs, $db, $type ) {
-               $pendingDBs[$type] = array_diff( $pendingDBs[$type], array( $db ) );
-               return $pendingDBs;
-       }
-
-       /**
-        * Check if the specified database has a job of the specified type in it.
-        * The type may be false to indicate "all".
-        * @param $type string
-        * @param $dbName string
-        * @return bool
-        */
-       private function checkJob( $type, $dbName ) {
-               return !JobQueueGroup::singleton( $dbName )->get( $type )->isEmpty();
-       }
-
-       /**
-        * Get all databases that have a pending job
-        * @return array
+        * Do all ready periodic jobs for all databases every 5 minutes (and .1% of the time)
+        * @return integer
         */
-       private function getPendingDbs() {
-               global $wgLocalDatabases;
+       private function executeReadyPeriodicTasks() {
+               global $wgLocalDatabases, $wgMemc;
 
-               $pendingDBs = array(); // (job type => (db list))
-               foreach ( $wgLocalDatabases as $db ) {
-                       $types = JobQueueGroup::singleton( $db )->getQueuesWithJobs();
-                       foreach ( $types as $type ) {
-                               $pendingDBs[$type][] = $db;
+               $count = 0;
+               $memcKey = 'jobqueue:periodic:lasttime';
+               $timestamp = (int)$wgMemc->get( $memcKey ); // UNIX timestamp or 0
+               if ( ( time() - $timestamp ) > 300 || mt_rand( 0, 999 ) == 0 ) { // 5 minutes
+                       if ( $wgMemc->add( "$memcKey:rebuild", 1, 1800 ) ) { // lock
+                               foreach ( $wgLocalDatabases as $db ) {
+                                       $count += JobQueueGroup::singleton( $db )->executeReadyPeriodicTasks();
+                               }
+                               $wgMemc->set( $memcKey, time() );
+                               $wgMemc->delete( "$memcKey:rebuild" ); // unlock
                        }
                }
 
-               return $pendingDBs;
+               return $count;
        }
 }