From 6f016f236d14c6eb16995f60e5195655963a0d3a Mon Sep 17 00:00:00 2001 From: Untone Date: Thu, 28 Mar 2024 14:05:06 +0300 Subject: [PATCH] caching-fixes --- resolvers/author.py | 37 +++++++++++++++++++++---------------- services/cache.py | 16 ++++++++-------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/resolvers/author.py b/resolvers/author.py index 3ae02aa7..25ff7caf 100644 --- a/resolvers/author.py +++ b/resolvers/author.py @@ -61,9 +61,10 @@ async def get_author(_, _info, slug='', author_id=None): logger.debug(f'GET {cache_key} -> {cache}') q = select(Author).where(Author.id == author_id) author_dict = None - if cache: + if cache and isinstance(cache, str): author_dict = json.loads(cache) else: + result = await get_authors_with_stat_cached(q) if result: [author] = result @@ -213,17 +214,19 @@ async def get_author_follows_topics(_, _info, slug='', user=None, author_id=None .first() ) author_id = author_id_result[0] if author_id_result else None - if author_id: - logger.debug(f'getting {author_id} follows topics') - rkey = f'author:{author_id}:follows-topics' - cached = await redis.execute('GET', rkey) - topics = json.loads(cached) if cached else author_follows_topics(author_id) - if not cached: - prepared = [topic.dict() for topic in topics] - await redis.execute('SET', rkey, json.dumps(prepared, cls=CustomJSONEncoder)) - return topics - else: + if not author_id: raise ValueError('Author not found') + logger.debug(f'getting {author_id} follows topics') + rkey = f'author:{author_id}:follows-topics' + cached = await redis.execute('GET', rkey) + topics = [] + if isinstance(cached, str): + topics = json.loads(cached) + if not cached: + topics = author_follows_topics(author_id) + prepared = [topic.dict() for topic in topics] + await redis.execute('SET', rkey, json.dumps(prepared, cls=CustomJSONEncoder)) + return topics @query.field('get_author_follows_authors') @@ -240,10 +243,11 @@ async def get_author_follows_authors(_, _info, slug='', user=None, author_id=Non logger.debug(f'getting {author_id} follows authors') rkey = f'author:{author_id}:follows-authors' cached = await redis.execute('GET', rkey) - authors = ( - json.loads(cached) if cached else author_follows_authors(author_id) - ) - if not cached: + authors = [] + if isinstance(cached, str): + authors = json.loads(cached) + if not authors: + authors = author_follows_authors(author_id) prepared = [author.dict() for author in authors] await redis.execute('SET', rkey, json.dumps(prepared, cls=CustomJSONEncoder)) return authors @@ -300,7 +304,8 @@ async def get_author_followers(_, _info, slug: str): return results else: logger.debug(f'@{slug} got followers cached') - return json.loads(cached) + if isinstance(cached, str): + return json.loads(cached) except Exception as exc: import traceback diff --git a/services/cache.py b/services/cache.py index 6b946460..14cafb96 100644 --- a/services/cache.py +++ b/services/cache.py @@ -87,9 +87,9 @@ async def update_follows_for_author( follows = [e for e in follows if e["id"] != entity_id] logger.debug(f'{entity['slug']} removed from what @{follower.slug} follows') if entity_type == "topic": - await set_follows_topics_cache(follows, follower.id) + await set_follows_topics_cache(follows, follower.id.scalar()) if entity_type == "author": - await set_follows_authors_cache(follows, follower.id) + await set_follows_authors_cache(follows, follower.id.scalar()) return follows @@ -166,25 +166,25 @@ def after_author_update(_mapper, _connection, author: Author): def after_topic_follower_insert(_mapper, _connection, target: TopicFollower): asyncio.create_task( - handle_topic_follower_change(target.topic, target.follower, True) + handle_topic_follower_change(target.topic.scalar(), target.follower.scalar(), True) ) def after_topic_follower_delete(_mapper, _connection, target: TopicFollower): asyncio.create_task( - handle_topic_follower_change(target.topic, target.follower, False) + handle_topic_follower_change(target.topic.scalar(), target.follower.scalar(), False) ) def after_author_follower_insert(_mapper, _connection, target: AuthorFollower): asyncio.create_task( - handle_author_follower_change(target.author, target.follower, True) + handle_author_follower_change(target.author.scalar(), target.follower.scalar(), True) ) def after_author_follower_delete(_mapper, _connection, target: AuthorFollower): asyncio.create_task( - handle_author_follower_change(target.author, target.follower, False) + handle_author_follower_change(target.author.scalar(), target.follower.scalar(), False) ) @@ -200,7 +200,7 @@ async def handle_author_follower_change( follows_authors = await redis.execute( "GET", f"author:{follower_id}:follows-authors" ) - if follows_authors: + if isinstance(follows_authors, str): follows_authors = json.loads(follows_authors) if not any(x.get("id") == author.id for x in follows_authors): follows_authors.append(author.dict()) @@ -233,7 +233,7 @@ async def handle_topic_follower_change( follows_topics = await redis.execute( "GET", f"author:{follower_id}:follows-topics" ) - if follows_topics: + if isinstance(follows_topics, str): follows_topics = json.loads(follows_topics) if not any(x.get("id") == topic.id for x in follows_topics): follows_topics.append(topic)