/** * 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 $cref * @param RedisException $e */ public function handleError(RedisConnRef $cref, RedisException $e) { $server = $cref->getServer(); $this->logger->error('Redis exception on server "{redis_server}"', array('redis_server' => $server, 'exception' => $e)); foreach ($this->connections[$server] as $key => $connection) { if ($cref->isConnIdentical($connection['conn'])) { $this->idlePoolSize -= $connection['free'] ? 1 : 0; unset($this->connections[$server][$key]); break; } } }
/** * Check the master link status of a Redis server that is configured as a slave. * @param RedisConnRef $conn * @return string|null Master link status (either 'up' or 'down'), or null * if the server is not a slave. */ protected function getMasterLinkStatus(RedisConnRef $conn) { $info = $conn->info(); return isset($info['master_link_status']) ? $info['master_link_status'] : null; }
/** * @param RedisConnRef $conn * @param string $slot * @param float $now * @return int|bool False on failure */ protected function registerAcquisitionTime(RedisConnRef $conn, $slot, $now) { static $script = <<<LUA \t\tlocal kSlots,kSlotsNextRelease,kSlotWaits = unpack(KEYS) \t\tlocal rSlot,rExpiry,rSess,rTime = unpack(ARGV) \t\t-- If rSlot is 'w' then the client was told to wake up but got no slot \t\tif rSlot ~= 'w' then \t\t\t-- Update the slot "next release" time \t\t\tredis.call('zAdd',kSlotsNextRelease,rTime + rExpiry,rSlot) \t\t\t-- Always keep renewing the expiry on use \t\t\tredis.call('expireAt',kSlots,math.ceil(rTime + rExpiry)) \t\t\tredis.call('expireAt',kSlotsNextRelease,math.ceil(rTime + rExpiry)) \t\tend \t\t-- Unregister this process as waiting \t\tredis.call('zRem',kSlotWaits,rSess) \t\treturn 1 LUA; return $conn->luaEval($script, [$this->getSlotListKey(), $this->getSlotRTimeSetKey(), $this->getWaitSetKey(), $slot, $this->lockTTL, $this->session, $now], 3); }
/** * This function should not be called outside JobQueueRedis * * @param string $uid * @param RedisConnRef $conn * @return Job|bool Returns false if the job does not exist * @throws JobQueueError * @throws UnexpectedValueException */ public function getJobFromUidInternal($uid, RedisConnRef $conn) { try { $data = $conn->hGet($this->getQueueKey('h-data'), $uid); if ($data === false) { return false; // not found } $item = $this->unserialize($data); if (!is_array($item)) { // this shouldn't happen throw new UnexpectedValueException("Could not find job with ID '{$uid}'."); } $title = Title::makeTitle($item['namespace'], $item['title']); $job = Job::factory($item['type'], $title, $item['params']); $job->metadata['uuid'] = $item['uuid']; $job->metadata['timestamp'] = $item['timestamp']; // Add in attempt count for debugging at showJobs.php $job->metadata['attempts'] = $conn->hGet($this->getQueueKey('h-attempts'), $uid); return $job; } catch (RedisException $e) { $this->throwRedisException($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 $cref * @param RedisException $e */ public function handleError(RedisConnRef $cref, RedisException $e) { $server = $cref->getServer(); wfDebugLog('redis', "Redis exception on server {$server}: " . $e->getMessage() . "\n"); foreach ($this->connections[$server] as $key => $connection) { if ($cref->isConnIdentical($connection['conn'])) { $this->idlePoolSize -= $connection['free'] ? 1 : 0; unset($this->connections[$server][$key]); break; } } }
/** * This function should not be called outside JobQueueRedis * * @param $uid string * @param $conn RedisConnRef * @return Job * @throws MWException */ public function getJobFromUidInternal($uid, RedisConnRef $conn) { try { $item = unserialize($conn->hGet($this->getQueueKey('h-data'), $uid)); if (!is_array($item)) { // this shouldn't happen throw new MWException("Could not find job with ID '{$uid}'."); } $title = Title::makeTitle($item['namespace'], $item['title']); $job = Job::factory($item['type'], $title, $item['params']); $job->metadata['uuid'] = $item['uuid']; return $job; } catch (RedisException $e) { $this->throwRedisException($this->server, $conn, $e); } }