Files
nonebot-plugin-tetris-stats/nonebot_plugin_tetris_stats/games/tetrio/api/cache.py
2024-05-16 05:59:18 +08:00

36 lines
1.3 KiB
Python

from asyncio import Lock
from datetime import datetime, timezone
from typing import ClassVar
from weakref import WeakValueDictionary
from aiocache import Cache as ACache # type: ignore[import-untyped]
from nonebot.compat import type_validate_json
from nonebot.log import logger
from ....utils.request import Request
from .schemas.base import FailedModel, SuccessModel
UTC = timezone.utc
class Cache:
cache = ACache(ACache.MEMORY)
task: ClassVar[WeakValueDictionary[str, Lock]] = WeakValueDictionary()
@classmethod
async def get(cls, url: str) -> bytes:
lock = cls.task.setdefault(url, Lock())
async with lock:
if (cached_data := await cls.cache.get(url)) is not None:
logger.debug(f'{url}: Cache hit!')
return cached_data
response_data = await Request.request(url)
parsed_data: SuccessModel | FailedModel = type_validate_json(SuccessModel | FailedModel, response_data) # type: ignore[arg-type]
if isinstance(parsed_data, SuccessModel):
await cls.cache.add(
url,
response_data,
(parsed_data.cache.cached_until - datetime.now(UTC)).total_seconds(),
)
return response_data