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 [];
     }
 }
示例#2
0
    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);
 }
示例#4
0
 /**
  * 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);
 }
示例#5
0
 /**
  * @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");
 }