【山大智云开发日志】seafdav分析(10)

2021SC@SDUSC

lock_storage.py:为“LockManager”实现两个存储提供程序。 这里定义了两种可选的锁存储类:一种是内存中的 (基于 dict),以及一种使用搁置的持久性低性能变体。

文件由LockStorageDict、LockStorageShelve两个类组成。

类LockStorageDict

使用字典的内存中锁管理器存储实现。 R/W 访问由 thread.lock 对象保护。 此外,为了使其与搁置字典一起使用,修改字典 成员通过重新分配完成,我们调用 _flush() 方法。 这显然不是持久的,但在某些情况下应该足够了。

类中函数get(self,token)负责返回一个令牌的锁字典。 如果锁不存在或已过期,则返回 None。 副作用:如果锁已过期,则会清除它并返回 None。

主要代码

    def get(self, token):
        self._lock.acquire_read()
        try:
            lock = self._dict.get(token)
            if lock is None:
                # Lock not found: purge dangling URL2TOKEN entries
                _logger.debug("Lock purged dangling: {}".format(token))
                self.delete(token)
                return None
            expire = float(lock["expire"])
            if expire >= 0 and expire < time.time():
                _logger.debug(
                    "Lock timed-out({}): {}".format(expire, lock_string(lock))
                )
                self.delete(token)
                return None
            return lock
        finally:
            self._lock.release()

函数create(self, path, lock):为资源路径创建直接锁。返回: 新的唯一锁定令牌。

注意:返回时可能会修改锁字典:

- lock['root'] 被忽略并设置为规范化的 <path>

- lock['timeout'] 可能被标准化并且比请求的短 

代码

    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.acquire_write()
        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 = normalize_lock_root(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

            validate_lock(lock)

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

            # Store lock
            self._dict[token] = lock

            # Store locked path reference
            key = "URL2TOKEN:{}".format(path)
            if key not 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}): {}".format(org_path, lock_string(lock))
            )
            return lock
        finally:
            self._lock.release()

函数refresh(self, token, timeout):修改现有锁的超时。 token: 有效的锁定令牌。 timeout: 以秒为单位的建议生命周期(-1 表示无限)。 实际到期时间可能比要求的要短! 返回: 锁字典。 如果令牌无效,则引发 ValueError

代码

assert token in self._dict, "Lock must exist"
        assert timeout == -1 or timeout > 0
        if timeout < 0 or timeout > LockStorageDict.LOCK_TIME_OUT_MAX:
            timeout = LockStorageDict.LOCK_TIME_OUT_MAX

        self._lock.acquire_write()
        try:
            # Note: shelve dictionary returns copies, so we must reassign
            # values:
            lock = self._dict[token]
            lock["timeout"] = timeout
            lock["expire"] = time.time() + timeout
            self._dict[token] = lock
            self._flush()
        finally:
            self._lock.release()
        return lock

函数get_lock_list(self, path, include_root, include_children, token_only):返回 <path> 的直接锁列表。 过期的锁*不会*返回(但可能会被清除)。

path: 规范化路径(utf8 编码字符串,没有尾随 '/')

include_root: 错误:不要添加 <path> 锁(只有在 include_children 时才有意义 是真的)。

include_children: True:还要检查现有锁的所有子路径。

token_only: True:仅返回令牌列表。 这可能会实施 一些供应商更有效。

返回: 有效锁字典列表(可能为空)

类LockStorageShelve使用搁置的低性能锁管理器实现。

主要代码

    def _flush(self):
        """Write persistent dictionary to disc."""
        _logger.debug("_flush()")
        self._lock.acquire_write()  # TODO: read access is enough?
        try:
            self._dict.sync()
        finally:
            self._lock.release()

    def clear(self):
        """Delete all entries."""
        self._lock.acquire_write()  # TODO: read access is enough?
        try:
            was_closed = self._dict is None
            if was_closed:
                self.open()
            if len(self._dict):
                self._dict.clear()
                self._dict.sync()
            if was_closed:
                self.close()
        finally:
            self._lock.release()

文件lock_storage_redis.py由类LockStorageRedis组成。

类LockStorageRedis使用 redis 的锁管理器实现!

函数refresh(self, token, timeout)修改现有锁的超时。 token: 有效的锁定令牌。 timeout: 以秒为单位的建议生命周期(-1 表示无限)。 实际到期时间可能比要求的要短! 返回: 锁字典。 如果令牌无效,则引发 ValueError。

代码

    def refresh(self, token, timeout):
        """Modify an existing lock's timeout.
        token:
            Valid lock token.
        timeout:
            Suggested lifetime in seconds (-1 for infinite).
            The real expiration time may be shorter than requested!
        Returns:
            Lock dictionary.
            Raises ValueError, if token is invalid.
        """
        assert self._redis.exists(self._redis_lock_prefix.format(token))
        assert timeout == -1 or timeout > 0
        if timeout < 0 or timeout > LockStorageRedis.LOCK_TIME_OUT_MAX:
            timeout = LockStorageRedis.LOCK_TIME_OUT_MAX

        # Note: shelve dictionary returns copies, so we must reassign
        # values:
        lock = pickle.loads(self._redis.get(self._redis_lock_prefix.format(token)))
        lock["timeout"] = timeout
        lock["expire"] = time.time() + timeout
        self._redis.set(
            self._redis_lock_prefix.format(token), pickle.dumps(lock), ex=int(timeout)
        )
        self._flush()
        return lock

文件middleware.py:抽象基础中间件类(可选使用)

由类BaseMiddleware组成。抽象基中间件类(可选)。 注意:这是一个方便的类,*可能*用于实现 WsgiDAV 中间件。这不是一个要求:任何实现 WSGI 规范可以添加到堆栈中。

WsgiDAV 中的派生类包括: wsgidav.dir_browser.WsgiDavDirBrowser wsgidav.debug_filter.WsgiDavDebugFilter

wsgidav.error_printer.ErrorPrinter

wsgidav.http_authenticator.HTTPAuthenticator

wsgidav.request_resolver.RequestResolver

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值