protected function doGetAllReadyWikiQueues() { $conn = $this->getConnection(); if (!$conn) { return []; } try { $map = $conn->hGetAll($this->getReadyQueueKey()); if (is_array($map) && isset($map['_epoch'])) { unset($map['_epoch']); // ignore $pendingDBs = []; // (type => list of wikis) foreach ($map as $key => $time) { list($type, $wiki) = $this->decodeQueueName($key); $pendingDBs[$type][] = $wiki; } } else { throw new UnexpectedValueException("No queue listing found; make sure redisJobChronService is running."); } return $pendingDBs; } catch (RedisException $e) { $this->redisPool->handleError($conn, $e); return []; } }
protected function freeLocksOnServer($lockSrv, array $pathsByType) { $status = StatusValue::newGood(); $pathList = call_user_func_array('array_merge', array_values($pathsByType)); $server = $this->lockServers[$lockSrv]; $conn = $this->redisPool->getConnection($server, $this->logger); if (!$conn) { foreach ($pathList as $path) { $status->fatal('lockmanager-fail-releaselock', $path); } return $status; } $pathsByKey = []; // (type:hash => path) map foreach ($pathsByType as $type => $paths) { $typeString = $type == LockManager::LOCK_SH ? 'SH' : 'EX'; foreach ($paths as $path) { $pathsByKey[$this->recordKeyForPath($path, $typeString)] = $path; } } try { static $script = <<<LUA \t\t\tlocal failed = {} \t\t\t-- Load input params (e.g. session) \t\t\tlocal rSession = unpack(ARGV) \t\t\tfor i,requestKey in ipairs(KEYS) do \t\t\t\tlocal _, _, rType, resourceKey = string.find(requestKey,"(%w+):(%w+)\$") \t\t\t\tlocal released = redis.call('hDel',resourceKey,rType .. ':' .. rSession) \t\t\t\tif released > 0 then \t\t\t\t\t-- Remove the whole structure if it is now empty \t\t\t\t\tif redis.call('hLen',resourceKey) == 0 then \t\t\t\t\t\tredis.call('del',resourceKey) \t\t\t\t\tend \t\t\t\telse \t\t\t\t\tfailed[#failed+1] = requestKey \t\t\t\tend \t\t\tend \t\t\treturn failed LUA; $res = $conn->luaEval($script, array_merge(array_keys($pathsByKey), [$this->session]), count($pathsByKey)); } catch (RedisException $e) { $res = false; $this->redisPool->handleError($conn, $e); } if ($res === false) { foreach ($pathList as $path) { $status->fatal('lockmanager-fail-releaselock', $path); } } else { foreach ($res as $key) { $status->fatal('lockmanager-fail-releaselock', $pathsByKey[$key]); } } return $status; }
/** * @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. * @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"); }