- # If we've got a pending job in a db, display it.
- if ( $pendingDBs ) {
- $this->output( $pendingDBs[mt_rand( 0, count( $pendingDBs ) - 1 )] );
+
+ do {
+ $again = false;
+
+ if ( $type === false ) {
+ $candidates = call_user_func_array( 'array_merge', $pendingDBs );
+ } elseif ( isset( $pendingDBs[$type] ) ) {
+ $candidates = $pendingDBs[$type];
+ } else {
+ $candidates = array();
+ }
+ if ( !$candidates ) {
+ return;
+ }
+
+ $db = $candidates[ mt_rand( 0, count( $candidates ) - 1 ) ];
+ if ( !$this->checkJob( $type, $db ) ) {
+ // This job is not available in the current database. Remove it from
+ // the cache.
+ if ( $type === false ) {
+ foreach ( $pendingDBs as $type2 => $dbs ) {
+ $pendingDBs[$type2] = array_diff( $pendingDBs[$type2], array( $db ) );
+ }
+ } else {
+ $pendingDBs[$type] = array_diff( $pendingDBs[$type], array( $db ) );
+ }
+
+ $wgMemc->set( $memcKey, $pendingDBs, 300 );
+ $again = true;
+ }
+ } while ( $again );
+
+ $this->output( $db . "\n" );
+ }
+
+ /**
+ * Check if the specified database has a job of the specified type in it.
+ * The type may be false to indicate "all".
+ */
+ function checkJob( $type, $db ) {
+ $lb = wfGetLB( $db );
+ $db = $lb->getConnection( DB_MASTER );
+ if ( $type === false ) {
+ $conds = array();
+ } else {
+ $conds = array( 'job_cmd' => $type );