Spaces:
Paused
Paused
# 声明:本代码仅供学习和研究目的使用。使用者应遵守以下原则: | |
# 1. 不得用于任何商业用途。 | |
# 2. 使用时应遵守目标平台的使用条款和robots.txt规则。 | |
# 3. 不得进行大规模爬取或对平台造成运营干扰。 | |
# 4. 应合理控制请求频率,避免给目标平台带来不必要的负担。 | |
# 5. 不得用于任何非法或不当的用途。 | |
# | |
# 详细许可条款请参阅项目根目录下的LICENSE文件。 | |
# 使用本代码即表示您同意遵守上述原则和LICENSE中的所有条款。 | |
# -*- coding: utf-8 -*- | |
# @Author : relakkes@gmail.com | |
# @Name : 程序员阿江-Relakkes | |
# @Time : 2024/6/2 11:05 | |
# @Desc : 本地缓存 | |
import asyncio | |
import time | |
from typing import Any, Dict, List, Optional, Tuple | |
from cache.abs_cache import AbstractCache | |
class ExpiringLocalCache(AbstractCache): | |
def __init__(self, cron_interval: int = 10): | |
""" | |
初始化本地缓存 | |
:param cron_interval: 定时清楚cache的时间间隔 | |
:return: | |
""" | |
self._cron_interval = cron_interval | |
self._cache_container: Dict[str, Tuple[Any, float]] = {} | |
self._cron_task: Optional[asyncio.Task] = None | |
# 开启定时清理任务 | |
self._schedule_clear() | |
def __del__(self): | |
""" | |
析构函数,清理定时任务 | |
:return: | |
""" | |
if self._cron_task is not None: | |
self._cron_task.cancel() | |
def get(self, key: str) -> Optional[Any]: | |
""" | |
从缓存中获取键的值 | |
:param key: | |
:return: | |
""" | |
value, expire_time = self._cache_container.get(key, (None, 0)) | |
if value is None: | |
return None | |
# 如果键已过期,则删除键并返回None | |
if expire_time < time.time(): | |
del self._cache_container[key] | |
return None | |
return value | |
def set(self, key: str, value: Any, expire_time: int) -> None: | |
""" | |
将键的值设置到缓存中 | |
:param key: | |
:param value: | |
:param expire_time: | |
:return: | |
""" | |
self._cache_container[key] = (value, time.time() + expire_time) | |
def keys(self, pattern: str) -> List[str]: | |
""" | |
获取所有符合pattern的key | |
:param pattern: 匹配模式 | |
:return: | |
""" | |
if pattern == '*': | |
return list(self._cache_container.keys()) | |
# 本地缓存通配符暂时将*替换为空 | |
if '*' in pattern: | |
pattern = pattern.replace('*', '') | |
return [key for key in self._cache_container.keys() if pattern in key] | |
def _schedule_clear(self): | |
""" | |
开启定时清理任务, | |
:return: | |
""" | |
try: | |
loop = asyncio.get_event_loop() | |
except RuntimeError: | |
loop = asyncio.new_event_loop() | |
asyncio.set_event_loop(loop) | |
self._cron_task = loop.create_task(self._start_clear_cron()) | |
def _clear(self): | |
""" | |
根据过期时间清理缓存 | |
:return: | |
""" | |
for key, (value, expire_time) in self._cache_container.items(): | |
if expire_time < time.time(): | |
del self._cache_container[key] | |
async def _start_clear_cron(self): | |
""" | |
开启定时清理任务 | |
:return: | |
""" | |
while True: | |
self._clear() | |
await asyncio.sleep(self._cron_interval) | |
if __name__ == '__main__': | |
cache = ExpiringLocalCache(cron_interval=2) | |
cache.set('name', '程序员阿江-Relakkes', 3) | |
print(cache.get('key')) | |
print(cache.keys("*")) | |
time.sleep(4) | |
print(cache.get('key')) | |
del cache | |
time.sleep(1) | |
print("done") | |