diff options
Diffstat (limited to 'maintenance/nextJobDB.php')
-rw-r--r-- | maintenance/nextJobDB.php | 127 |
1 files changed, 85 insertions, 42 deletions
diff --git a/maintenance/nextJobDB.php b/maintenance/nextJobDB.php index 6af5cbec..75855bb3 100644 --- a/maintenance/nextJobDB.php +++ b/maintenance/nextJobDB.php @@ -2,59 +2,102 @@ /** * Pick a database that has pending jobs * - * @file + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @todo Make this work on PostgreSQL and maybe other database servers * @ingroup Maintenance */ -$options = array( 'type' ); - -require_once( 'commandLine.inc' ); - -$type = isset($options['type']) - ? $options['type'] - : false; +require_once( dirname(__FILE__) . '/Maintenance.php' ); -$mckey = $type === false - ? "jobqueue:dbs" - : "jobqueue:dbs:$type"; - -$pendingDBs = $wgMemc->get( $mckey ); -if ( !$pendingDBs ) { - $pendingDBs = array(); - # Cross-reference DBs by master DB server - $dbsByMaster = array(); - foreach ( $wgLocalDatabases as $db ) { - $lb = wfGetLB( $db ); - $dbsByMaster[$lb->getServerName(0)][] = $db; +class nextJobDB extends Maintenance { + public function __construct() { + parent::__construct(); + $this->mDescription = "Pick a database that has pending jobs"; + $this->addOption( 'type', "The type of job to search for", false, true ); } - foreach ( $dbsByMaster as $master => $dbs ) { - $dbConn = wfGetDB( DB_MASTER, array(), $dbs[0] ); - $stype = $dbConn->addQuotes($type); + public function execute() { + global $wgMemc; + $type = $this->getOption( 'type', false ); + $mckey = $type === false + ? "jobqueue:dbs" + : "jobqueue:dbs:$type"; + $pendingDBs = $wgMemc->get( $mckey ); - # Padding row for MySQL bug - $sql = "(SELECT '-------------------------------------------')"; - foreach ( $dbs as $dbName ) { - if ( $sql != '' ) { - $sql .= ' UNION '; - } - if ($type === false) - $sql .= "(SELECT '$dbName' FROM `$dbName`.job LIMIT 1)"; - else - $sql .= "(SELECT '$dbName' FROM `$dbName`.job WHERE job_cmd=$stype LIMIT 1)"; + # If we didn't get it from the cache + if( !$pendingDBs ) { + $pendingDBs = $this->getPendingDbs( $type ); + $wgMemc->get( $mckey, $pendingDBs, 300 ); } - $res = $dbConn->query( $sql, 'nextJobDB.php' ); - $row = $dbConn->fetchRow( $res ); // discard padding row - while ( $row = $dbConn->fetchRow( $res ) ) { - $pendingDBs[] = $row[0]; + # If we've got a pending job in a db, display it. + if ( $pendingDBs ) { + $this->output( $pendingDBs[mt_rand(0, count( $pendingDBs ) - 1)] ); } } - $wgMemc->set( $mckey, $pendingDBs, 300 ); -} + /** + * Get all databases that have a pending job + * @param $type String Job type + * @return array + */ + private function getPendingDbs( $type ) { + global $wgLocalDatabases; + $pendingDBs = array(); + # Cross-reference DBs by master DB server + $dbsByMaster = array(); + foreach ( $wgLocalDatabases as $db ) { + $lb = wfGetLB( $db ); + $dbsByMaster[$lb->getServerName(0)][] = $db; + } -if ( $pendingDBs ) { - echo $pendingDBs[mt_rand(0, count( $pendingDBs ) - 1)]; -} + foreach ( $dbsByMaster as $master => $dbs ) { + $dbConn = wfGetDB( DB_MASTER, array(), $dbs[0] ); + $stype = $dbConn->addQuotes( $type ); + + # Padding row for MySQL bug + $sql = "(SELECT '-------------------------------------------' as db)"; + foreach ( $dbs as $wikiId ) { + if ( $sql != '' ) { + $sql .= ' UNION '; + } + list( $dbName, $tablePrefix ) = wfSplitWikiID( $wikiId ); + $dbConn->tablePrefix( $tablePrefix ); + $jobTable = $dbConn->tableName( 'job' ); + + if ( $type === false ) + $sql .= "(SELECT '$wikiId' as db FROM $dbName.$jobTable LIMIT 1)"; + else + $sql .= "(SELECT '$wikiId' as db FROM $dbName.$jobTable WHERE job_cmd=$stype LIMIT 1)"; + } + $res = $dbConn->query( $sql, __METHOD__ ); + $first = true; + foreach ( $res as $row ) { + if ( $first ) { + // discard padding row + $first = false; + continue; + } + $pendingDBs[] = $row->db; + } + } + return $pendingDBs; + } +} +$maintClass = "nextJobDb"; +require_once( DO_MAINTENANCE ); |