예제 #1
0
    def getLockList(self, path, includeRoot, includeChildren, tokenOnly):
        """Return a list of direct locks for <path>.

        Expired locks are *not* returned (but may be purged).

        path:
            Normalized path (utf8 encoded string, no trailing '/')
        includeRoot:
            False: don't add <path> lock (only makes sense, when includeChildren
            is True).
        includeChildren:
            True: Also check all sub-paths for existing locks.
        tokenOnly:
            True: only a list of token is returned. This may be implemented
            more efficiently by some providers.
        Returns:
            List of valid lock dictionaries (may be empty).
        """
        assert path and path.startswith("/")
        assert includeRoot or includeChildren

        def __appendLocks(toklist):
            # Since we can do this quickly, we use self.get() even if
            # tokenOnly is set, so expired locks are purged.
            for token in toklist:
                lock_db = self.get_lock_db_from_token(token)
                if lock_db:
                    if tokenOnly:
                        lockList.append(lock_db.token)
                    else:
                        lockList.append(from_base_to_dict(lock_db))

        path = normalizeLockRoot(path)
        self._lock.acquireRead()
        try:
            tokList = self._session.query(
                Url2Token.token).filter(Url2Token.path == path).all()
            lockList = []
            if includeRoot:
                __appendLocks(tokList)

            if includeChildren:
                for url, in self._session.query(Url2Token.path).group_by(
                        Url2Token.path):
                    if util.isChildUri(path, url):
                        __appendLocks(
                            self._session.query(
                                Url2Token.token).filter(Url2Token.path == url))

            return lockList
        finally:
            self._lock.release()
예제 #2
0
    def getLockList(self, path, includeRoot, includeChildren, tokenOnly):
        """Return a list of direct locks for <path>.

        Expired locks are *not* returned (but may be purged).

        path:
            Normalized path (utf8 encoded string, no trailing '/')
        includeRoot:
            False: don't add <path> lock (only makes sense, when includeChildren
            is True).
        includeChildren:
            True: Also check all sub-paths for existing locks.
        tokenOnly:
            True: only a list of token is returned. This may be implemented
            more efficiently by some providers.
        Returns:
            List of valid lock dictionaries (may be empty).
        """
        assert compat.is_native(path)
        assert path and path.startswith("/")
        assert includeRoot or includeChildren

        def __appendLocks(toklist):
            # Since we can do this quickly, we use self.get() even if
            # tokenOnly is set, so expired locks are purged.
            for token in toklist:
                lock = self.get(token)
                if lock:
                    if tokenOnly:
                        lockList.append(lock["token"])
                    else:
                        lockList.append(lock)

        path = normalizeLockRoot(path)
        self._lock.acquireRead()
        try:
            key = "URL2TOKEN:%s" % path
            tokList = self._dict.get(key, [])
            lockList = []
            if includeRoot:
                __appendLocks(tokList)

            if includeChildren:
                for u, ltoks in self._dict.items():
                    if util.isChildUri(key, u):
                        __appendLocks(ltoks)

            return lockList
        finally:
            self._lock.release()
예제 #3
0
    def getLockList(self, path, includeRoot, includeChildren, tokenOnly):
        """Return a list of direct locks for <path>.

        Expired locks are *not* returned (but may be purged).

        path:
            Normalized path (utf8 encoded string, no trailing '/')
        includeRoot:
            False: don't add <path> lock (only makes sense, when includeChildren
            is True).
        includeChildren:
            True: Also check all sub-paths for existing locks.
        tokenOnly:
            True: only a list of token is returned. This may be implemented
            more efficiently by some providers.
        Returns:
            List of valid lock dictionaries (may be empty).
        """
        assert path and path.startswith("/")
        assert includeRoot or includeChildren

        def __appendLocks(toklist):
            # Since we can do this quickly, we use self.get() even if
            # tokenOnly is set, so expired locks are purged.
            for token in toklist:
                lock_db = self.get_lock_db_from_token(token)
                if lock_db:
                    if tokenOnly:
                        lockList.append(lock_db.token)
                    else:
                        lockList.append(from_base_to_dict(lock_db))

        path = normalizeLockRoot(path)
        self._lock.acquireRead()
        try:
            tokList = self._session.query(Url2Token.token).filter(Url2Token.path == path).all()
            lockList = []
            if includeRoot:
                __appendLocks(tokList)

            if includeChildren:
                for url, in self._session.query(Url2Token.path).group_by(Url2Token.path):
                    if util.isChildUri(path, url):
                        __appendLocks(self._session.query(Url2Token.token).filter(Url2Token.path == url))

            return lockList
        finally:
            self._lock.release()
예제 #4
0
    def getLockList(self, path, includeRoot, includeChildren, tokenOnly):
        """Return a list of direct locks for <path>.

        Expired locks are *not* returned (but may be purged).

        path:
            Normalized path (utf8 encoded string, no trailing '/')
        includeRoot:
            False: don't add <path> lock (only makes sense, when includeChildren
            is True).
        includeChildren:
            True: Also check all sub-paths for existing locks.
        tokenOnly:
            True: only a list of token is returned. This may be implemented
            more efficiently by some providers.
        Returns:
            List of valid lock dictionaries (may be empty).
        """
        assert path and path.startswith("/")
        assert includeRoot or includeChildren
        def __appendLocks(toklist):
            # Since we can do this quickly, we use self.get() even if
            # tokenOnly is set, so expired locks are purged.
            for token in toklist:
                lock = self.get(token)
                if lock:
                    if tokenOnly:
                        lockList.append(lock["token"])
                    else:
                        lockList.append(lock)

        path = normalizeLockRoot(path)
        self._lock.acquireRead()
        try:
            key = "URL2TOKEN:%s" % path
            tokList = self._dict.get(key, [])
            lockList = []
            if includeRoot:
                __appendLocks(tokList)

            if includeChildren:
                for u, ltoks in self._dict.items():
                    if util.isChildUri(key, u):
                        __appendLocks(ltoks)

            return lockList
        finally:
            self._lock.release()
예제 #5
0
    def create(self, path, lock):
        """Create a direct lock for a resource path.

        path:
            Normalized path (utf8 encoded string, no trailing '/')
        lock:
            lock dictionary, without a token entry
        Returns:
            New unique lock token.: <lock

        **Note:** the lock dictionary may be modified on return:

        - lock['root'] is ignored and set to the normalized <path>
        - lock['timeout'] may be normalized and shorter than requested
        - lock['token'] is added
        """
        self._lock.acquireWrite()
        try:
            # We expect only a lock definition, not an existing lock
            assert lock.get("token") is None
            assert lock.get("expire") is None, "Use timeout instead of expire"
            assert path and "/" in path

            # Normalize root: /foo/bar
            org_path = path
            path = normalizeLockRoot(path)
            lock["root"] = path

            # Normalize timeout from ttl to expire-date
            timeout = float(lock.get("timeout"))
            if timeout is None:
                timeout = LockStorage.LOCK_TIME_OUT_DEFAULT
            elif timeout < 0 or timeout > LockStorage.LOCK_TIME_OUT_MAX:
                timeout = LockStorage.LOCK_TIME_OUT_MAX

            lock["timeout"] = timeout
            lock["expire"] = time.time() + timeout

            validateLock(lock)

            token = generateLockToken()
            lock["token"] = token

            # Store lock
            lock_db = from_dict_to_base(lock)

            self._session.add(lock_db)

            # Store locked path reference
            url2token = Url2Token(
                path=path,
                token=token
            )

            self._session.add(url2token)
            self._session.commit()

            self._flush()
            _logger.debug("LockStorageDict.set(%r): %s" % (org_path, lockString(lock)))
            #            print("LockStorageDict.set(%r): %s" % (org_path, lockString(lock)))
            return lock
        finally:
            self._lock.release()
예제 #6
0
    def create(self, path, lock):
        """Create a direct lock for a resource path.

        path:
            Normalized path (utf8 encoded string, no trailing '/')
        lock:
            lock dictionary, without a token entry
        Returns:
            New unique lock token.: <lock

        **Note:** the lock dictionary may be modified on return:

        - lock['root'] is ignored and set to the normalized <path>
        - lock['timeout'] may be normalized and shorter than requested
        - lock['token'] is added
        """
        self._lock.acquireWrite()
        try:
            # We expect only a lock definition, not an existing lock
            assert lock.get("token") is None
            assert lock.get("expire") is None, "Use timeout instead of expire"
            assert path and "/" in path

            # Normalize root: /foo/bar
            org_path = path
            path = normalizeLockRoot(path)
            lock["root"] = path

            # Normalize timeout from ttl to expire-date
            timeout = float(lock.get("timeout"))
            if timeout is None:
                timeout = LockStorage.LOCK_TIME_OUT_DEFAULT
            elif timeout < 0 or timeout > LockStorage.LOCK_TIME_OUT_MAX:
                timeout = LockStorage.LOCK_TIME_OUT_MAX

            lock["timeout"] = timeout
            lock["expire"] = time.time() + timeout

            validateLock(lock)

            token = generateLockToken()
            lock["token"] = token

            # Store lock
            lock_db = from_dict_to_base(lock)

            self._session.add(lock_db)

            # Store locked path reference
            url2token = Url2Token(path=path, token=token)

            self._session.add(url2token)
            self._session.commit()

            self._flush()
            _logger.debug("LockStorageDict.set(%r): %s" %
                          (org_path, lockString(lock)))
            #            print("LockStorageDict.set(%r): %s" % (org_path, lockString(lock)))
            return lock
        finally:
            self._lock.release()
예제 #7
0
    def create(self, path, lock):
        """Create a direct lock for a resource path.
        
        path:
            Normalized path (utf8 encoded string, no trailing '/')
        lock:
            lock dictionary, without a token entry 
        Returns:
            New unique lock token.: <lock
        
        **Note:** the lock dictionary may be modified on return:

        - lock['root'] is ignored and set to the normalized <path>
        - lock['timeout'] may be normalized and shorter than requested
        - lock['token'] is added
        """
        self._lock.acquireWrite()
        try:
            # We expect only a lock definition, not an existing lock
            assert lock.get("token") is None
            assert lock.get("expire") is None, "Use timeout instead of expire"
            assert path and "/" in path

            # Normalize root: /foo/bar
            org_path = path
            path = normalizeLockRoot(path)
            lock["root"] = path

            # Normalize timeout from ttl to expire-date
            timeout = float(lock.get("timeout"))
            if timeout is None:
                timeout = LockStorageDict.LOCK_TIME_OUT_DEFAULT
            elif timeout < 0 or timeout > LockStorageDict.LOCK_TIME_OUT_MAX:
                timeout = LockStorageDict.LOCK_TIME_OUT_MAX

            lock["timeout"] = timeout
            lock["expire"] = time.time() + timeout

            validateLock(lock)

            token = generateLockToken()
            lock["token"] = token

            # Store lock
            self._dict[token] = lock

            # Store locked path reference
            key = "URL2TOKEN:%s" % path
            if not key in self._dict:
                self._dict[key] = [token]
            else:
                # Note: Shelve dictionary returns copies, so we must reassign values:
                tokList = self._dict[key]
                tokList.append(token)
                self._dict[key] = tokList
            self._flush()
            _logger.debug("LockStorageDict.set(%r): %s" %
                          (org_path, lockString(lock)))
            #            print("LockStorageDict.set(%r): %s" % (org_path, lockString(lock)))
            return lock
        finally:
            self._lock.release()
예제 #8
0
    def create(self, path, lock):
        """Create a direct lock for a resource path.

        path:
            Normalized path (utf8 encoded string, no trailing '/')
        lock:
            lock dictionary, without a token entry
        Returns:
            New unique lock token.: <lock

        **Note:** the lock dictionary may be modified on return:

        - lock['root'] is ignored and set to the normalized <path>
        - lock['timeout'] may be normalized and shorter than requested
        - lock['token'] is added
        """
        self._lock.acquireWrite()
        try:
            # We expect only a lock definition, not an existing lock
            assert lock.get("token") is None
            assert lock.get("expire") is None, "Use timeout instead of expire"
            assert path and "/" in path

            # Normalize root: /foo/bar
            org_path = path
            path = normalizeLockRoot(path)
            lock["root"] = path

            # Normalize timeout from ttl to expire-date
            timeout = float(lock.get("timeout"))
            if timeout is None:
                timeout = LockStorageDict.LOCK_TIME_OUT_DEFAULT
            elif timeout < 0 or timeout > LockStorageDict.LOCK_TIME_OUT_MAX:
                timeout = LockStorageDict.LOCK_TIME_OUT_MAX

            lock["timeout"] = timeout
            lock["expire"] = time.time() + timeout

            validateLock(lock)

            token = generateLockToken()
            lock["token"] = token

            # Store lock
            self._dict[token] = lock

            # Store locked path reference
            key = "URL2TOKEN:%s" % path
            if not key in self._dict:
                self._dict[key] = [ token ]
            else:
                # Note: Shelve dictionary returns copies, so we must reassign values:
                tokList = self._dict[key]
                tokList.append(token)
                self._dict[key] = tokList
            self._flush()
            _logger.debug("LockStorageDict.set(%r): %s" % (org_path, lockString(lock)))
#            print("LockStorageDict.set(%r): %s" % (org_path, lockString(lock)))
            return lock
        finally:
            self._lock.release()