/** * @see RCFeedEngine::send */ public function send(array $feed, $line) { $parsed = wfParseUrl($feed['uri']); $server = $parsed['host']; $options = ['serializer' => 'none']; $channel = 'rc'; if (isset($parsed['port'])) { $server .= ":{$parsed['port']}"; } if (isset($parsed['query'])) { parse_str($parsed['query'], $options); } if (isset($parsed['pass'])) { $options['password'] = $parsed['pass']; } if (isset($parsed['path'])) { $channel = str_replace('/', '.', ltrim($parsed['path'], '/')); } $pool = RedisConnectionPool::singleton($options); $conn = $pool->getConnection($server); if ($conn !== false) { $conn->publish($channel, $line); return true; } else { return false; } }
/** * Get a connection to the server that handles all sub-queues for this queue * * @return RedisConnRef|bool Returns false on failure * @throws MWException */ protected function getConnection() { $conn = false; foreach ($this->servers as $server) { $conn = $this->redisPool->getConnection($server, $this->logger); if ($conn) { break; } } return $conn; }
/** * Acquire a Redis connection. * * @access protected * @param string [Optiona] Server group key. * Example: 'cache' would look up $wgRedisServers['cached'] * Default: Uses the first index of $wgRedisServers. * @param array [Optional] Additional options, will merge and overwrite default options. * - connectTimeout : The timeout for new connections, in seconds. * Optional, default is 1 second. * - persistent : Set this to true to allow connections to persist across * multiple web requests. False by default. * - password : The authentication password, will be sent to Redis in clear text. * Optional, if it is unspecified, no AUTH command will be sent. * - serializer : Set to "php", "igbinary", or "none". Default is "php". * @param boolean [Optional] Force a new connection, useful when forking processes. * @return mixed Object RedisConnRef or false on failure. */ public static function getClient($group = null, $options = [], $newConnection = false) { global $wgRedisServers; if (!extension_loaded('redis')) { throw new MWException(__METHOD__ . " - The PHP Redis extension is not available. Please enable it on the server to use RedisCache."); } if (empty($wgRedisServers) || !is_array($wgRedisServers)) { MWDebug::log(__METHOD__ . " - \$wgRedisServers must be configured for RedisCache to function."); return false; } if (empty($group)) { $group = 0; $server = current($wgRedisServers); } else { $server = $wgRedisServers[$group]; } if ($newConnection === false && array_key_exists($group, self::$servers)) { return self::$servers[$group]; } if (empty($server) || !is_array($server)) { throw new MWException(__METHOD__ . " - An invalid server group key was passed."); } $pool = \RedisConnectionPool::singleton(array_merge($server['options'], $options)); $redis = $pool->getConnection($server['host'] . ":" . $server['port']); //Concatenate these together for MediaWiki weirdness so it can split them later. if ($redis instanceof RedisConnRef) { //Set up any extra options. RedisConnectionPool does not handle the prefix automatically. if (!empty($server['options']['prefix'])) { $redis->setOption(Redis::OPT_PREFIX, $server['options']['prefix']); } try { $pong = $redis->ping(); if ($pong === '+PONG') { self::$servers[$group] = $redis; } else { $redis = false; } } catch (RedisException $e) { //People using HAProxy will find it will lie about a Redis cluster being healthy when the master is down, but the slaves are up. Doing a PING will cause an immediate disconnect. self::$lastError = $e->getMessage(); $redis = false; } } return $redis; }
/** * @return Status Uses RediConnRef as value on success */ protected function getConnection() { if (!isset($this->conn)) { $conn = false; $servers = $this->ring->getLocations($this->key, 3); ArrayUtils::consistentHashSort($servers, $this->key); foreach ($servers as $server) { $conn = $this->pool->getConnection($this->serversByLabel[$server], $this->logger); if ($conn) { break; } } if (!$conn) { return Status::newFatal('pool-servererror', implode(', ', $servers)); } $this->conn = $conn; } return Status::newGood($this->conn); }
function __destruct() { $this->pool->freeConnection($this->server, $this->conn); }
/** * @param RedisConnRef $conn * @param Exception $e */ protected function handleException(RedisConnRef $conn, $e) { $this->redisPool->handleError($conn, $e); }
/** * The redis extension throws an exception in response to various read, write * and protocol errors. Sometimes it also closes the connection, sometimes * not. The safest response for us is to explicitly destroy the connection * object and let it be reopened during the next request. */ protected function handleException( $server, RedisConnRef $conn, $e ) { $this->redisPool->handleException( $server, $conn, $e ); }
/** * The redis extension throws an exception in response to various read, write * and protocol errors. Sometimes it also closes the connection, sometimes * not. The safest response for us is to explicitly destroy the connection * object and let it be reopened during the next request. * @param RedisConnRef $conn * @param Exception $e */ protected function handleException(RedisConnRef $conn, $e) { $this->setLastError(BagOStuff::ERR_UNEXPECTED); $this->redisPool->handleError($conn, $e); }
/** * @param RedisConnRef $conn * @param RedisException $e * @throws JobQueueError */ protected function throwRedisException(RedisConnRef $conn, $e) { $this->redisPool->handleError($conn, $e); throw new JobQueueError("Redis server error: {$e->getMessage()}\n"); }
protected function prepareEnvironment() { global $wgMemc; // Don't share DB, storage, or memcached connections MediaWikiServices::resetChildProcessServices(); FileBackendGroup::destroySingleton(); LockManagerGroup::destroySingletons(); JobQueueGroup::destroySingletons(); ObjectCache::clear(); RedisConnectionPool::destroySingletons(); $wgMemc = null; }
protected function prepareEnvironment() { global $wgMemc; // Don't share DB, storage, or memcached connections wfGetLBFactory()->destroyInstance(); FileBackendGroup::destroySingleton(); LockManagerGroup::destroySingletons(); JobQueueGroup::destroySingletons(); ObjectCache::clear(); RedisConnectionPool::destroySingletons(); $wgMemc = null; }
protected function isServerUp($lockSrv) { return (bool) $this->redisPool->getConnection($this->lockServers[$lockSrv]); }
/** * @param $server string * @param $conn RedisConnRef * @param $e RedisException * @throws MWException */ protected function throwRedisException($server, RedisConnRef $conn, $e) { $this->redisPool->handleException($server, $conn, $e); throw new MWException("Redis server error: {$e->getMessage()}\n"); }
protected function isServerUp($lockSrv) { $conn = $this->redisPool->getConnection($this->lockServers[$lockSrv], $this->logger); return (bool) $conn; }
/** * Destroy all singleton() instances * @since 1.27 */ public static function destroySingletons() { self::$instances = []; }