Merge maintenance-work branch (now with less errors!):
[lhc/web/wiklou.git] / maintenance / nextJobDB.php
1 <?php
2 /**
3 * Pick a database that has pending jobs
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @ingroup Maintenance
21 */
22
23 require_once( "Maintenance.php" );
24
25 class nextJobDB extends Maintenance {
26 public function __construct() {
27 parent::__construct();
28 $this->mDescription = "Pick a database that has pending jobs";
29 $this->addOption( 'type', "The type of job to search for", false, true );
30 }
31 public function execute() {
32 global $wgMemc;
33 $type = $this->getOption( 'type', false );
34 $mckey = $type === false
35 ? "jobqueue:dbs"
36 : "jobqueue:dbs:$type";
37 $pendingDBs = $wgMemc->get( $mckey );
38
39 # If we didn't get it from the cache
40 if( !$pendingDBs ) {
41 $pendingDBs = $this->getPendingDbs( $type );
42 $wgMemc->get( $mckey, $pendingDBs, 300 );
43 }
44 # If we've got a pending job in a db, display it.
45 if ( $pendingDBs ) {
46 $this->output( $pendingDBs[mt_rand(0, count( $pendingDBs ) - 1)] );
47 }
48 }
49
50 /**
51 * Get all databases that have a pending job
52 * @param $type String Job type
53 * @return array
54 */
55 private function getPendingDbs( $type ) {
56 global $wgLocalDatabases;
57 $pendingDBs = array();
58 # Cross-reference DBs by master DB server
59 $dbsByMaster = array();
60 foreach ( $wgLocalDatabases as $db ) {
61 $lb = wfGetLB( $db );
62 $dbsByMaster[$lb->getServerName(0)][] = $db;
63 }
64
65 foreach ( $dbsByMaster as $master => $dbs ) {
66 $dbConn = wfGetDB( DB_MASTER, array(), $dbs[0] );
67 $stype = $dbConn->addQuotes($type);
68 $jobTable = $dbConn->getTable( 'job' );
69
70 # Padding row for MySQL bug
71 $sql = "(SELECT '-------------------------------------------')";
72 foreach ( $dbs as $dbName ) {
73 if ( $sql != '' ) {
74 $sql .= ' UNION ';
75 }
76 if ($type === false)
77 $sql .= "(SELECT '$dbName' FROM `$dbName`.$jobTable LIMIT 1)";
78 else
79 $sql .= "(SELECT '$dbName' FROM `$dbName`.$jobTable WHERE job_cmd=$stype LIMIT 1)";
80 }
81 $res = $dbConn->query( $sql, __METHOD__ );
82 $row = $dbConn->fetchRow( $res ); // discard padding row
83 while ( $row = $dbConn->fetchRow( $res ) ) {
84 $pendingDBs[] = $row[0];
85 }
86 }
87 }
88 }
89
90 $maintClass = "nextJobDb";
91 require_once( DO_MAINTENANCE );