From 5a492e408c6e3b3b37246c711592b61db6afd2df Mon Sep 17 00:00:00 2001 From: FirePlank <44502537+FirePlank@users.noreply.github.com> Date: Tue, 28 Nov 2023 23:00:15 +0200 Subject: [PATCH] switched to using async-lru --- bot/extensions/adventofcode/utils.py | 51 +++++++--------------------- bot/extensions/adventofcode/views.py | 6 ++-- poetry.lock | 16 ++++++++- pyproject.toml | 1 + 4 files changed, 31 insertions(+), 43 deletions(-) diff --git a/bot/extensions/adventofcode/utils.py b/bot/extensions/adventofcode/utils.py index 131bc0a6..ef3921ea 100644 --- a/bot/extensions/adventofcode/utils.py +++ b/bot/extensions/adventofcode/utils.py @@ -3,6 +3,7 @@ from zoneinfo import ZoneInfo import discord +from async_lru import alru_cache from pydantic import BaseModel, validator from bot.config import settings @@ -81,45 +82,17 @@ def set_name_to_anonymous(cls, val: Optional[str]) -> str: return val -class Cache: - def __init__(self): - self.global_cache = {"data": "", "expiration": datetime(1972, 1, 1)} - self.local_cache = {"data": {}, "expiration": datetime(1972, 1, 1)} +@alru_cache(ttl=60) +async def fetch_leaderboard(local: bool = False) -> Union[str, dict]: + url = f"https://adventofcode.com/{YEAR}/leaderboard" + if local: + url += f"/private/view/{LEADERBOARD_ID}.json" - async def fetch_leaderboard(self, local: bool = False) -> Union[str, dict]: - now = datetime.now() - - if local: - if now > self.local_cache["expiration"]: - response = await self._fetch_from_api(local=True) - self.local_cache["data"] = response - self.local_cache["expiration"] = now + timedelta(minutes=1) - else: - response = self.local_cache["data"] - else: - if now > self.global_cache["expiration"]: - response = await self._fetch_from_api(local=False) - self.global_cache["data"] = response - self.global_cache["expiration"] = now + timedelta(minutes=1) + async with http.session.get(url, headers=AOC_REQUEST_HEADERS, raise_for_status=True) as resp: + if resp.status == 200: + if local: + response = await resp.json() else: - response = self.global_cache["data"] - - return response - - @staticmethod - async def _fetch_from_api(local: bool = False) -> Union[str, dict]: - url = f"https://adventofcode.com/{YEAR}/leaderboard" - if local: - url += f"/private/view/{LEADERBOARD_ID}.json" - - async with http.session.get(url, headers=AOC_REQUEST_HEADERS, raise_for_status=True) as resp: - if resp.status == 200: - if local: - response = await resp.json() - else: - response = await resp.text() - - return response - + response = await resp.text() -cache = Cache() + return response diff --git a/bot/extensions/adventofcode/views.py b/bot/extensions/adventofcode/views.py index 39de63d3..13e7da4d 100644 --- a/bot/extensions/adventofcode/views.py +++ b/bot/extensions/adventofcode/views.py @@ -7,7 +7,7 @@ from discord import ui from bot import core -from bot.extensions.adventofcode.utils import LEADERBOARD_ID, YEAR, Member, cache, home_embed, ordinal +from bot.extensions.adventofcode.utils import LEADERBOARD_ID, YEAR, Member, fetch_leaderboard, home_embed, ordinal class CreateAdventOfCodeView(ui.View): @@ -23,7 +23,7 @@ async def home(self, interaction: core.InteractionType, _button: ui.Button): label="Local Leaderboard", style=discord.ButtonStyle.gray, emoji="👥", custom_id=LOCAL_LEADERBOARD_CUSTOM_ID ) async def local_leaderboard(self, interaction: core.InteractionType, button: ui.Button): - leaderboard = await cache.fetch_leaderboard(local=True) + leaderboard = await fetch_leaderboard(local=True) members = [Member(**member_data) for member_data in leaderboard["members"].values()] @@ -54,7 +54,7 @@ async def local_leaderboard(self, interaction: core.InteractionType, button: ui. label="Global Leaderboard", style=discord.ButtonStyle.gray, emoji="🌎", custom_id=GLOBAL_LEADERBOARD_CUSTOM_ID ) async def global_leaderboard(self, interaction: core.InteractionType, button: ui.Button): - raw_html = await cache.fetch_leaderboard(local=False) + raw_html = await fetch_leaderboard(local=False) soup = BeautifulSoup(raw_html, "html.parser") embed = discord.Embed( diff --git a/poetry.lock b/poetry.lock index a7b6ac39..37aede9f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -137,6 +137,20 @@ files = [ six = ">=1.6.1,<2.0" wheel = ">=0.23.0,<1.0" +[[package]] +name = "async-lru" +version = "2.0.4" +description = "Simple LRU cache for asyncio" +optional = false +python-versions = ">=3.8" +files = [ + {file = "async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627"}, + {file = "async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} + [[package]] name = "async-timeout" version = "4.0.2" @@ -1331,4 +1345,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "0faf30752db0cb31ba0d77ff3b1ede7423c660351dc1f9d036870cd7ec86ef5e" +content-hash = "3f63299e4f321c26e411a6af6ec89184569f08009d6b6455f218c04917a3247f" diff --git a/pyproject.toml b/pyproject.toml index c7986713..f88bf540 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ beautifulsoup4 = "^4.12.2" tabulate = "^0.9.0" pillow = "^10.1.0" tzdata = "^2023.3" +async-lru = "^2.0.4" [tool.poetry.group.dev.dependencies] isort = "^5.12.0"