use-cached-authors

This commit is contained in:
Untone 2024-03-12 15:26:36 +03:00
parent d5a9a18c04
commit 26a527473f
2 changed files with 24 additions and 7 deletions

View File

@ -9,7 +9,7 @@ from sqlalchemy_searchable import search
from orm.author import Author, AuthorFollower from orm.author import Author, AuthorFollower
from orm.shout import ShoutAuthor, ShoutTopic from orm.shout import ShoutAuthor, ShoutTopic
from orm.topic import Topic from orm.topic import Topic
from resolvers.stat import get_with_stat, author_follows_authors, author_follows_topics from resolvers.stat import get_authors_with_stat_cached, author_follows_authors, author_follows_topics
from services.cache import set_author_cache, update_author_followers_cache from services.cache import set_author_cache, update_author_followers_cache
from services.auth import login_required from services.auth import login_required
from services.db import local_session from services.db import local_session
@ -44,7 +44,7 @@ async def get_author(_, _info, slug='', author_id=None):
try: try:
if slug: if slug:
q = select(Author).select_from(Author).filter(Author.slug == slug) q = select(Author).select_from(Author).filter(Author.slug == slug)
result = get_with_stat(q) result = get_authors_with_stat_cached(q)
if result: if result:
[author] = result [author] = result
author_id = author.id author_id = author.id
@ -57,7 +57,7 @@ async def get_author(_, _info, slug='', author_id=None):
if cache: if cache:
author_dict = json.loads(cache) author_dict = json.loads(cache)
else: else:
result = get_with_stat(q) result = get_authors_with_stat_cached(q)
if result: if result:
[author] = result [author] = result
author_dict = author.dict() author_dict = author.dict()
@ -90,7 +90,7 @@ async def get_author_by_user_id(user_id: str):
return author return author
q = select(Author).filter(Author.user == user_id) q = select(Author).filter(Author.user == user_id)
result = get_with_stat(q) result = get_authors_with_stat_cached(q)
if result: if result:
[author] = result [author] = result
await set_author_cache(author.dict()) await set_author_cache(author.dict())
@ -137,7 +137,7 @@ def load_authors_by(_, _info, by, limit, offset):
# q = q.distinct() # q = q.distinct()
q = q.limit(limit).offset(offset) q = q.limit(limit).offset(offset)
authors = get_with_stat(q) authors = get_authors_with_stat_cached(q)
return authors return authors
@ -266,7 +266,7 @@ async def get_author_followers(_, _info, slug: str):
author_follower_alias.follower == Author.id, author_follower_alias.follower == Author.id,
), ),
) )
results = get_with_stat(q) results = get_authors_with_stat_cached(q)
_ = asyncio.create_task( _ = asyncio.create_task(
update_author_followers_cache( update_author_followers_cache(
author_id, [x.dict() for x in results] author_id, [x.dict() for x in results]
@ -288,4 +288,4 @@ async def get_author_followers(_, _info, slug: str):
@query.field('search_authors') @query.field('search_authors')
def search_authors(_, _info, what: str): def search_authors(_, _info, what: str):
q = search(select(Author), what) q = search(select(Author), what)
return get_with_stat(q) return get_authors_with_stat_cached(q)

View File

@ -1,3 +1,5 @@
import json
from sqlalchemy import func, distinct, select, join, and_, case, true, cast, Integer from sqlalchemy import func, distinct, select, join, and_, case, true, cast, Integer
from sqlalchemy.orm import aliased from sqlalchemy.orm import aliased
@ -7,6 +9,7 @@ from services.db import local_session
from orm.author import AuthorFollower, Author, AuthorRating from orm.author import AuthorFollower, Author, AuthorRating
from orm.shout import ShoutTopic, ShoutAuthor, Shout from orm.shout import ShoutTopic, ShoutAuthor, Shout
from services.logger import root_logger as logger from services.logger import root_logger as logger
from services.rediscache import redis
def add_topic_stat_columns(q): def add_topic_stat_columns(q):
@ -196,6 +199,20 @@ def get_with_stat(q):
return records return records
async def get_authors_with_stat_cached(q):
try:
records = []
with local_session() as session:
for x in session.execute(q):
stat_str = await redis.execute('GET', f'id:{x.id}:{'author'}')
if isinstance(stat_str, str):
x.stat = json.loads(stat_str).get('stat')
records.append(x)
except Exception as exc:
raise Exception(exc)
return records
def author_follows_authors(author_id: int): def author_follows_authors(author_id: int):
af = aliased(AuthorFollower, name="af") af = aliased(AuthorFollower, name="af")
q = ( q = (