From fe140da2a79dee0bc6850451f076d83deb009edb Mon Sep 17 00:00:00 2001 From: Alexander Ledovsky Date: Fri, 30 Aug 2024 10:15:40 +0300 Subject: [PATCH 1/2] Added expire to add_memes_to_queue_by_key --- src/redis.py | 11 ++++++++--- tests/conftest.py | 11 ----------- tests/test_redis.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 tests/test_redis.py diff --git a/src/redis.py b/src/redis.py index 193de15..c8c3480 100644 --- a/src/redis.py +++ b/src/redis.py @@ -60,10 +60,15 @@ async def get_meme_queue_length_by_key(key: str) -> int: return await redis_client.scard(key) -async def add_memes_to_queue_by_key(key: str, memes: list[dict]) -> int: +async def add_memes_to_queue_by_key( + key: str, memes: list[dict], + expire: int = 3600 + ) -> None: jsoned_memes = [orjson.dumps(meme) for meme in memes] - # TODO: add ttl, probably using redis transactions - return await redis_client.sadd(key, *jsoned_memes) + p = await redis_client.pipeline(transaction=True) + await p.sadd(key, *jsoned_memes) + await p.expire(key, expire) + await p.execute(raise_on_error=True) def get_user_info_key(user_id: int) -> str: diff --git a/tests/conftest.py b/tests/conftest.py index 83f8ada..558768f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,8 +5,6 @@ import pytest_asyncio from async_asgi_testclient import TestClient -from src.main import app - @pytest.fixture(autouse=True, scope="session") def run_migrations() -> None: @@ -23,12 +21,3 @@ def event_loop() -> Generator[asyncio.AbstractEventLoop, None, None]: loop = asyncio.get_event_loop_policy().new_event_loop() yield loop loop.close() - - -@pytest_asyncio.fixture -async def client() -> AsyncGenerator[TestClient, None]: - host, port = "127.0.0.1", "9000" - scope = {"client": (host, port)} - - async with TestClient(app, scope=scope) as client: - yield client diff --git a/tests/test_redis.py b/tests/test_redis.py new file mode 100644 index 0000000..b01a62a --- /dev/null +++ b/tests/test_redis.py @@ -0,0 +1,29 @@ +from datetime import datetime + +import asyncio + +import pytest +import pytest_asyncio + +from src import redis + + +@pytest.mark.asyncio +async def test_add_memes_to_queue_by_key_ok(): + user_id = 999 + queue_key = redis.get_meme_queue_key(user_id) + + memes = [ + {'id': 1, 'recommended_by': 'best_algo'}, + {'id': 2, 'recommended_by': 'best_algo'}, + ] + + await redis.add_memes_to_queue_by_key(queue_key, memes, expire=1) + + stored = await redis.redis_client.smembers(queue_key) + assert len(stored) == 2 + + await asyncio.sleep(3) + + stored = await redis.redis_client.smembers(queue_key) + assert len(stored) == 0 \ No newline at end of file From 879afc5148b00c43bade8438a30df29278015295 Mon Sep 17 00:00:00 2001 From: Alexander Ledovsky Date: Fri, 30 Aug 2024 17:30:51 +0300 Subject: [PATCH 2/2] changed get_next_meme_for_user; if the queue is empty run the new queue generation syncronously --- src/tgbot/senders/next_message.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tgbot/senders/next_message.py b/src/tgbot/senders/next_message.py index 2285e9e..773cf30 100644 --- a/src/tgbot/senders/next_message.py +++ b/src/tgbot/senders/next_message.py @@ -51,8 +51,10 @@ async def get_next_meme_for_user(user_id: int) -> MemeData | None: while True: meme = await meme_queue.get_next_meme_for_user(user_id) if not meme: # no memes in queue - asyncio.create_task(meme_queue.check_queue(user_id)) - return None + await meme_queue.generate_recommendations(user_id, limit=5) + meme = await meme_queue.get_next_meme_for_user(user_id) + if not meme: + return None exists = await user_meme_reaction_exists(user_id, meme.id) if not exists: # this meme wasn't sent yet