2244532baed131497c7ba73411ed8e4d52ffa214
[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 * @todo Make this work on PostgreSQL and maybe other database servers
21 * @ingroup Maintenance
22 */
23
24 require_once( dirname(__FILE__) . '/Maintenance.php' );
25
26 class nextJobDB extends Maintenance {
27 public function __construct() {
28 parent::__construct();
29 $this->mDescription = "Pick a database that has pending jobs";
30 $this->addOption( 'type', "The type of job to search for", false, true );
31 }
32 public function execute() {
33 global $wgMemc;
34 $type = $this->getOption( 'type', false );
35 $mckey = $type === false
36 ? "jobqueue:dbs"
37 : "jobqueue:dbs:$type";
38 $pendingDBs = $wgMemc->get( $mckey );
39
40 # If we didn't get it from the cache
41 if( !$pendingDBs ) {
42 $pendingDBs = $this->getPendingDbs( $type );
43 $wgMemc->get( $mckey, $pendingDBs, 300 );
44 }
45 # If we've got a pending job in a db, display it.
46 if ( $pendingDBs ) {
47 $this->output( $pendingDBs[mt_rand(0, count( $pendingDBs ) - 1)] );
48 }
49 }
50
51 /**
52 * Get all databases that have a pending job
53 * @param $type String Job type
54 * @return array
55 */
56 private function getPendingDbs( $type ) {
57 global $wgLocalDatabases;
58 $pendingDBs = array();
59 # Cross-reference DBs by master DB server
60 $dbsByMaster = array();
61 foreach ( $wgLocalDatabases as $db ) {
62 $lb = wfGetLB( $db );
63 $dbsByMaster[$lb->getServerName(0)][] = $db;
64 }
65
66 foreach ( $dbsByMaster as $master => $dbs ) {
67 $dbConn = wfGetDB( DB_MASTER, array(), $dbs[0] );
68 $stype = $dbConn->addQuotes($type);
69
70
71 # Padding row for MySQL bug
72 $sql = "(SELECT '-------------------------------------------' as db)";
73 foreach ( $dbs as $wikiId ) {
74 if ( $sql != '' ) {
75 $sql .= ' UNION ';
76 }
77
78 list( $dbName, $tablePrefix ) = wfSplitWikiID( $wikiId );
79 $dbConn->tablePrefix( $tablePrefix );
80 $jobTable = $dbConn->tableName( 'job' );
81
82 if ( $type === false )
83 $sql .= "(SELECT '$wikiId' as db FROM $dbName.$jobTable LIMIT 1)";
84 else
85 $sql .= "(SELECT '$wikiId' as db FROM $dbName.$jobTable WHERE job_cmd=$stype LIMIT 1)";
86 }
87 $res = $dbConn->query( $sql, __METHOD__ );
88 $first = true;
89 foreach ( $res as $row ) {
90 if ( $first ) {
91 // discard padding row
92 $first = false;
93 continue;
94 }
95 $pendingDBs[] = $row->db;
96 }
97 }
98 return $pendingDBs;
99 }
100 }
101
102 $maintClass = "nextJobDb";
103 require_once( DO_MAINTENANCE );