Ejemplo n.º 1
0
 /**
  * @param $info array|null
  */
 function __construct($info)
 {
     parent::__construct($info);
     $this->wiki = $info['wiki'];
     list($this->dbName, $this->tablePrefix) = wfSplitWikiID($this->wiki);
     $this->hasSharedCache = $info['hasSharedCache'];
 }
Ejemplo n.º 2
0
 /**
  * Get a memcached key
  * @return string
  */
 public static function memcKey()
 {
     global $wgRegexBlockDatabase;
     $args = func_get_args();
     if ($wgRegexBlockDatabase === false) {
         return call_user_func_array('wfMemcKey', $args);
     } else {
         $newArgs = array_merge(wfSplitWikiID($wgRegexBlockDatabase), $args);
         return call_user_func_array('wfForeignMemcKey', $newArgs);
     }
 }
Ejemplo n.º 3
0
 /**
  * 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;
     }
     foreach ($dbsByMaster as $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;
 }
Ejemplo n.º 4
0
 /**
  * @param $group
  * @return String
  */
 public static function getGlobalRulesKey($group)
 {
     global $wgAbuseFilterIsCentral, $wgAbuseFilterCentralDB;
     if (!$wgAbuseFilterIsCentral) {
         list($globalSite, $globalPrefix) = wfSplitWikiID($wgAbuseFilterCentralDB);
         return wfForeignMemcKey($globalSite, $globalPrefix, 'abusefilter', 'rules', $group);
     }
     return wfMemcKey('abusefilter', 'rules', $group);
 }
Ejemplo n.º 5
0
 /**
  * Get all databases that have a pending job
  * @param $type String Job type
  * @return array
  */
 private function getPendingDbs()
 {
     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;
     }
     foreach ($dbsByMaster as $dbs) {
         $dbConn = wfGetDB(DB_MASTER, array(), $dbs[0]);
         # Padding row for MySQL bug
         $pad = str_repeat('-', 40);
         $sql = "(SELECT '{$pad}' as db, '{$pad}' as job_cmd)";
         foreach ($dbs as $wikiId) {
             if ($sql != '') {
                 $sql .= ' UNION ';
             }
             list($dbName, $tablePrefix) = wfSplitWikiID($wikiId);
             $dbConn->tablePrefix($tablePrefix);
             $jobTable = $dbConn->tableName('job');
             $sql .= "(SELECT DISTINCT '{$wikiId}' as db, job_cmd FROM {$dbName}.{$jobTable} GROUP BY job_cmd)";
         }
         $res = $dbConn->query($sql, __METHOD__);
         $first = true;
         foreach ($res as $row) {
             if ($first) {
                 // discard padding row
                 $first = false;
                 continue;
             }
             $pendingDBs[$row->job_cmd][] = $row->db;
         }
     }
     return $pendingDBs;
 }
Ejemplo n.º 6
0
 /**
  * @param string $name
  * @return mixed
  */
 private function getCachedConfigVar($name)
 {
     global $wgConf, $wgMemc;
     if ($this->wiki === wfWikiID()) {
         return $GLOBALS[$name];
         // common case
     } else {
         list($db, $prefix) = wfSplitWikiID($this->wiki);
         $key = wfForeignMemcKey($db, $prefix, 'configvalue', $name);
         $value = $wgMemc->get($key);
         // ('v' => ...) or false
         if (is_array($value)) {
             return $value['v'];
         } else {
             $value = $wgConf->getConfig($this->wiki, $name);
             $wgMemc->set($key, array('v' => $value), 86400 + mt_rand(0, 86400));
             return $value;
         }
     }
 }
Ejemplo n.º 7
0
 /**
  * @param string $property
  * @return string
  */
 private function getCacheKey($property)
 {
     list($db, $prefix) = wfSplitWikiID($this->wiki);
     $cluster = is_string($this->cluster) ? $this->cluster : 'main';
     return wfForeignMemcKey($db, $prefix, 'jobqueue', $cluster, $this->type, $property);
 }
Ejemplo n.º 8
0
 /**
  * Get cache key
  */
 protected function cacheKey()
 {
     $args = func_get_args();
     $args = array_merge(wfSplitWikiID($this->mDb), $args);
     return call_user_func_array('wfForeignMemcKey', $args);
 }
Ejemplo n.º 9
0
	/**
	 * @return string
	 */
	private function getCacheKey( $property ) {
		list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
		return wfForeignMemcKey( $db, $prefix, 'jobqueue', $this->type, $property );
	}
Ejemplo n.º 10
0
 /**
  * @param $path string
  * @return string
  */
 protected function recordKeyForPath($path)
 {
     $hash = LockManager::sha1Base36($path);
     list($db, $prefix) = wfSplitWikiID($this->wikiId);
     return wfForeignMemcKey($db, $prefix, __CLASS__, 'locks', $hash);
 }
Ejemplo n.º 11
0
 /**
  * @param string $prop
  * @param string|null $type Override this for sibling queues
  * @return string
  */
 private function getQueueKey($prop, $type = null)
 {
     $type = is_string($type) ? $type : $this->type;
     list($db, $prefix) = wfSplitWikiID($this->wiki);
     $keyspace = $prefix ? "{$db}-{$prefix}" : $db;
     $parts = array($keyspace, 'jobqueue', $type, $prop);
     // Parts are typically ASCII, but encode for sanity to escape ":"
     return implode(':', array_map('rawurlencode', $parts));
 }
Ejemplo n.º 12
0
	/**
	 * Open a connection to a foreign DB, or return one if it is already open.
	 *
	 * Increments a reference count on the returned connection which locks the
	 * connection to the requested wiki. This reference count can be
	 * decremented by calling reuseConnection().
	 *
	 * If a connection is open to the appropriate server already, but with the wrong
	 * database, it will be switched to the right database and returned, as long as
	 * it has been freed first with reuseConnection().
	 *
	 * On error, returns false, and the connection which caused the
	 * error will be available via $this->mErrorConnection.
	 *
	 * @param $i Integer: server index
	 * @param string $wiki wiki ID to open
	 * @return DatabaseBase
	 */
	function openForeignConnection( $i, $wiki ) {
		wfProfileIn( __METHOD__ );
		list( $dbName, $prefix ) = wfSplitWikiID( $wiki );
		if ( isset( $this->mConns['foreignUsed'][$i][$wiki] ) ) {
			// Reuse an already-used connection
			$conn = $this->mConns['foreignUsed'][$i][$wiki];
			wfDebug( __METHOD__ . ": reusing connection $i/$wiki\n" );
		} elseif ( isset( $this->mConns['foreignFree'][$i][$wiki] ) ) {
			// Reuse a free connection for the same wiki
			$conn = $this->mConns['foreignFree'][$i][$wiki];
			unset( $this->mConns['foreignFree'][$i][$wiki] );
			$this->mConns['foreignUsed'][$i][$wiki] = $conn;
			wfDebug( __METHOD__ . ": reusing free connection $i/$wiki\n" );
		} elseif ( !empty( $this->mConns['foreignFree'][$i] ) ) {
			// Reuse a connection from another wiki
			$conn = reset( $this->mConns['foreignFree'][$i] );
			$oldWiki = key( $this->mConns['foreignFree'][$i] );

			if ( !$conn->selectDB( $dbName ) ) {
				$this->mLastError = "Error selecting database $dbName on server " .
					$conn->getServer() . " from client host " . wfHostname() . "\n";
				$this->mErrorConnection = $conn;
				$conn = false;
			} else {
				$conn->tablePrefix( $prefix );
				unset( $this->mConns['foreignFree'][$i][$oldWiki] );
				$this->mConns['foreignUsed'][$i][$wiki] = $conn;
				wfDebug( __METHOD__ . ": reusing free connection from $oldWiki for $wiki\n" );
			}
		} else {
			// Open a new connection
			$server = $this->mServers[$i];
			$server['serverIndex'] = $i;
			$server['foreignPoolRefCount'] = 0;
			$server['foreign'] = true;
			$conn = $this->reallyOpenConnection( $server, $dbName );
			if ( !$conn->isOpen() ) {
				wfDebug( __METHOD__ . ": error opening connection for $i/$wiki\n" );
				$this->mErrorConnection = $conn;
				$conn = false;
			} else {
				$conn->tablePrefix( $prefix );
				$this->mConns['foreignUsed'][$i][$wiki] = $conn;
				wfDebug( __METHOD__ . ": opened new connection for $i/$wiki\n" );
			}
		}

		// Increment reference count
		if ( $conn ) {
			$refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
			$conn->setLBInfo( 'foreignPoolRefCount', $refCount + 1 );
		}
		wfProfileOut( __METHOD__ );
		return $conn;
	}
Ejemplo n.º 13
0
 /**
  * @param $prop string
  * @param $type string|null
  * @return string
  */
 private function getQueueKey($prop, $type = null)
 {
     $type = is_string($type) ? $type : $this->type;
     list($db, $prefix) = wfSplitWikiID($this->wiki);
     if (strlen($this->key)) {
         // namespaced queue (for testing)
         return wfForeignMemcKey($db, $prefix, 'jobqueue', $type, $this->key, $prop);
     } else {
         return wfForeignMemcKey($db, $prefix, 'jobqueue', $type, $prop);
     }
 }
Ejemplo n.º 14
0
 /**
  * @param string $name
  * @return mixed
  */
 private function getCachedConfigVar($name)
 {
     global $wgConf;
     if ($this->wiki === wfWikiID()) {
         return $GLOBALS[$name];
         // common case
     } else {
         $cache = ObjectCache::getLocalClusterInstance();
         list($db, $prefix) = wfSplitWikiID($this->wiki);
         $key = wfForeignMemcKey($db, $prefix, 'configvalue', $name);
         $value = $cache->get($key);
         // ('v' => ...) or false
         if (is_array($value)) {
             return $value['v'];
         } else {
             $value = $wgConf->getConfig($this->wiki, $name);
             $cache->set($key, array('v' => $value), $cache::TTL_DAY + mt_rand(0, $cache::TTL_DAY));
             return $value;
         }
     }
 }
Ejemplo n.º 15
0
 /**
  * Open a connection to a foreign DB, or return one if it is already open.
  *
  * Increments a reference count on the returned connection which locks the
  * connection to the requested wiki. This reference count can be
  * decremented by calling reuseConnection().
  *
  * If a connection is open to the appropriate server already, but with the wrong
  * database, it will be switched to the right database and returned, as long as
  * it has been freed first with reuseConnection().
  *
  * On error, returns false, and the connection which caused the
  * error will be available via $this->mErrorConnection.
  *
  * @param int $i Server index
  * @param string $wiki Wiki ID to open
  * @return DatabaseBase
  */
 private function openForeignConnection($i, $wiki)
 {
     list($dbName, $prefix) = wfSplitWikiID($wiki);
     if (isset($this->mConns['foreignUsed'][$i][$wiki])) {
         // Reuse an already-used connection
         $conn = $this->mConns['foreignUsed'][$i][$wiki];
         wfDebug(__METHOD__ . ": reusing connection {$i}/{$wiki}\n");
     } elseif (isset($this->mConns['foreignFree'][$i][$wiki])) {
         // Reuse a free connection for the same wiki
         $conn = $this->mConns['foreignFree'][$i][$wiki];
         unset($this->mConns['foreignFree'][$i][$wiki]);
         $this->mConns['foreignUsed'][$i][$wiki] = $conn;
         wfDebug(__METHOD__ . ": reusing free connection {$i}/{$wiki}\n");
     } elseif (!empty($this->mConns['foreignFree'][$i])) {
         // Reuse a connection from another wiki
         $conn = reset($this->mConns['foreignFree'][$i]);
         $oldWiki = key($this->mConns['foreignFree'][$i]);
         // The empty string as a DB name means "don't care".
         // DatabaseMysqlBase::open() already handle this on connection.
         if ($dbName !== '' && !$conn->selectDB($dbName)) {
             $this->mLastError = "Error selecting database {$dbName} on server " . $conn->getServer() . " from client host " . wfHostname() . "\n";
             $this->mErrorConnection = $conn;
             $conn = false;
         } else {
             $conn->tablePrefix($prefix);
             unset($this->mConns['foreignFree'][$i][$oldWiki]);
             $this->mConns['foreignUsed'][$i][$wiki] = $conn;
             wfDebug(__METHOD__ . ": reusing free connection from {$oldWiki} for {$wiki}\n");
         }
     } else {
         // Open a new connection
         $server = $this->mServers[$i];
         $server['serverIndex'] = $i;
         $server['foreignPoolRefCount'] = 0;
         $server['foreign'] = true;
         $conn = $this->reallyOpenConnection($server, $dbName);
         if (!$conn->isOpen()) {
             wfDebug(__METHOD__ . ": error opening connection for {$i}/{$wiki}\n");
             $this->mErrorConnection = $conn;
             $conn = false;
         } else {
             $conn->tablePrefix($prefix);
             $this->mConns['foreignUsed'][$i][$wiki] = $conn;
             wfDebug(__METHOD__ . ": opened new connection for {$i}/{$wiki}\n");
         }
     }
     // Increment reference count
     if ($conn) {
         $refCount = $conn->getLBInfo('foreignPoolRefCount');
         $conn->setLBInfo('foreignPoolRefCount', $refCount + 1);
     }
     return $conn;
 }
Ejemplo n.º 16
0
 /**
  * @param string $signature Hash identifier of the root job
  * @return string
  */
 protected function getRootJobCacheKey($signature)
 {
     list($db, $prefix) = wfSplitWikiID($this->wiki);
     return wfForeignMemcKey($db, $prefix, 'jobqueue', $this->type, 'rootjob', $signature);
 }
Ejemplo n.º 17
0
 /**
  * Get the database name and prefix based on the wiki ID
  * @param bool|string $wiki
  * @return array
  */
 private function getDBNameAndPrefix($wiki = false)
 {
     if ($wiki === false) {
         global $wgDBname, $wgDBprefix;
         return array($wgDBname, $wgDBprefix);
     } else {
         return wfSplitWikiID($wiki);
     }
 }
Ejemplo n.º 18
0
 /**
  * @return string
  */
 private function getEmptinessCacheKey()
 {
     list($db, $prefix) = wfSplitWikiID($this->wiki);
     return wfForeignMemcKey($db, $prefix, 'jobqueue', $this->type, 'isempty');
 }