TopShouts -> ShoutsCache

This commit is contained in:
Untone 2021-10-31 20:55:59 +03:00
parent 3a6531bcaa
commit af36e842cd
2 changed files with 37 additions and 37 deletions

View File

@ -13,7 +13,7 @@ from auth.oauth import oauth_login, oauth_authorize
from auth.email import email_authorize from auth.email import email_authorize
from redis import redis from redis import redis
from resolvers.base import resolvers from resolvers.base import resolvers
from resolvers.zine import GitTask, TopShouts from resolvers.zine import GitTask, ShoutsCache
from orm.shout import ShoutViewStorage from orm.shout import ShoutViewStorage
@ -30,7 +30,7 @@ middleware = [
async def start_up(): async def start_up():
await redis.connect() await redis.connect()
git_task = asyncio.create_task(GitTask.git_task_worker()) git_task = asyncio.create_task(GitTask.git_task_worker())
top_shouts_task = asyncio.create_task(TopShouts.worker()) shouts_cache_task = asyncio.create_task(ShoutsCache.worker())
view_storage_task = asyncio.create_task(ShoutViewStorage.worker()) view_storage_task = asyncio.create_task(ShoutViewStorage.worker())
async def shutdown(): async def shutdown():

View File

@ -69,7 +69,7 @@ class GitTask:
print("git task worker error = %s" % (err)) print("git task worker error = %s" % (err))
class TopShouts: class ShoutsCache:
limit = 50 limit = 50
period = 60*60 #1 hour period = 60*60 #1 hour
month_ago = datetime.now() - timedelta(days = 30) month_ago = datetime.now() - timedelta(days = 30)
@ -80,15 +80,15 @@ class TopShouts:
with local_session() as session: with local_session() as session:
stmt = select(Shout).\ stmt = select(Shout).\
order_by(desc("createdAt")).\ order_by(desc("createdAt")).\
limit(TopShouts.limit) limit(ShoutsCache.limit)
shouts = [] shouts = []
for row in session.execute(stmt): for row in session.execute(stmt):
shout = row.Shout shout = row.Shout
shout.rating = await ShoutRatingStorage.get_rating(shout.id) shout.rating = await ShoutRatingStorage.get_rating(shout.id)
shout.views = await ShoutViewStorage.get_view(shout.id) shout.views = await ShoutViewStorage.get_view(shout.id)
shouts.append(shout) shouts.append(shout)
async with TopShouts.lock: async with ShoutsCache.lock:
TopShouts.recent_shouts = shouts ShoutsCache.recent_shouts = shouts
@staticmethod @staticmethod
@ -98,15 +98,15 @@ class TopShouts:
join(ShoutRating).\ join(ShoutRating).\
group_by(Shout.id).\ group_by(Shout.id).\
order_by(desc("rating")).\ order_by(desc("rating")).\
limit(TopShouts.limit) limit(ShoutsCache.limit)
shouts = [] shouts = []
for row in session.execute(stmt): for row in session.execute(stmt):
shout = row.Shout shout = row.Shout
shout.rating = row.rating shout.rating = row.rating
shout.views = await ShoutViewStorage.get_view(shout.id) shout.views = await ShoutViewStorage.get_view(shout.id)
shouts.append(shout) shouts.append(shout)
async with TopShouts.lock: async with ShoutsCache.lock:
TopShouts.top_overall = shouts ShoutsCache.top_overall = shouts
@staticmethod @staticmethod
async def prepare_top_month(): async def prepare_top_month():
@ -116,57 +116,57 @@ class TopShouts:
stmt = select(Shout, func.sum(ShoutRating.value).label("rating")).\ stmt = select(Shout, func.sum(ShoutRating.value).label("rating")).\
join(ShoutRating).\ join(ShoutRating).\
join(ShoutViewByDay).\ join(ShoutViewByDay).\
where(ShoutViewByDay.day > TopShouts.month_ago).\ where(ShoutViewByDay.day > ShoutsCache.month_ago).\
group_by(Shout.id).\ group_by(Shout.id).\
order_by(desc("rating")).\ order_by(desc("rating")).\
limit(TopShouts.limit) limit(ShoutsCache.limit)
shouts = [] shouts = []
for row in session.execute(stmt): for row in session.execute(stmt):
shout = row.Shout shout = row.Shout
shout.rating = row.rating shout.rating = row.rating
shout.views = await ShoutViewStorage.get_view(shout.id) shout.views = await ShoutViewStorage.get_view(shout.id)
shouts.append(shout) shouts.append(shout)
async with TopShouts.lock: async with ShoutsCache.lock:
TopShouts.top_month = shouts ShoutsCache.top_month = shouts
@staticmethod @staticmethod
async def prepare_top_viewed(): async def prepare_top_viewed():
with local_session() as session: with local_session() as session:
stmt = select(Shout, func.sum(ShoutViewByDay.value).label("view")).\ stmt = select(Shout, func.sum(ShoutViewByDay.value).label("view")).\
join(ShoutViewByDay).\ join(ShoutViewByDay).\
where(ShoutViewByDay.day > TopShouts.month_ago).\ where(ShoutViewByDay.day > ShoutsCache.month_ago).\
group_by(Shout.id).\ group_by(Shout.id).\
order_by(desc("view")).\ order_by(desc("view")).\
limit(TopShouts.limit) limit(ShoutsCache.limit)
shouts = [] shouts = []
for row in session.execute(stmt): for row in session.execute(stmt):
shout = row.Shout shout = row.Shout
shout.rating = await ShoutRatingStorage.get_rating(shout.id) shout.rating = await ShoutRatingStorage.get_rating(shout.id)
shout.view = row.view shout.view = row.view
shouts.append(shout) shouts.append(shout)
async with TopShouts.lock: async with ShoutsCache.lock:
TopShouts.top_viewed = shouts ShoutsCache.top_viewed = shouts
@staticmethod @staticmethod
async def prepare_top_authors(): async def prepare_top_authors():
with local_session() as session: with local_session() as session:
shout_with_view = select(Shout.id, func.sum(ShoutViewByDay.value).label("view")).\ shout_with_view = select(Shout.id, func.sum(ShoutViewByDay.value).label("view")).\
join(ShoutViewByDay).\ join(ShoutViewByDay).\
where(ShoutViewByDay.day > TopShouts.month_ago).\ where(ShoutViewByDay.day > ShoutsCache.month_ago).\
group_by(Shout.id).\ group_by(Shout.id).\
order_by(desc("view")).cte() order_by(desc("view")).cte()
stmt = select(ShoutAuthor.user, func.sum(shout_with_view.c.view).label("view")).\ stmt = select(ShoutAuthor.user, func.sum(shout_with_view.c.view).label("view")).\
join(shout_with_view, ShoutAuthor.shout == shout_with_view.c.id).\ join(shout_with_view, ShoutAuthor.shout == shout_with_view.c.id).\
group_by(ShoutAuthor.user).\ group_by(ShoutAuthor.user).\
order_by(desc("view")).\ order_by(desc("view")).\
limit(TopShouts.limit) limit(ShoutsCache.limit)
authors = {} authors = {}
for row in session.execute(stmt): for row in session.execute(stmt):
authors[row.user] = row.view authors[row.user] = row.view
authors_ids = authors.keys() authors_ids = authors.keys()
authors = session.query(User).filter(User.id.in_(authors_ids)).all() authors = session.query(User).filter(User.id.in_(authors_ids)).all()
async with TopShouts.lock: async with ShoutsCache.lock:
TopShouts.top_authors = authors ShoutsCache.top_authors = authors
@staticmethod @staticmethod
@ -175,42 +175,42 @@ class TopShouts:
while True: while True:
try: try:
print("shouts cache updating...") print("shouts cache updating...")
await TopShouts.prepare_top_month() await ShoutsCache.prepare_top_month()
await TopShouts.prepare_top_overall() await ShoutsCache.prepare_top_overall()
await TopShouts.prepare_top_viewed() await ShoutsCache.prepare_top_viewed()
await TopShouts.prepare_recent_shouts() await ShoutsCache.prepare_recent_shouts()
await TopShouts.prepare_top_authors() await ShoutsCache.prepare_top_authors()
print("shouts cache update finished") print("shouts cache update finished")
except Exception as err: except Exception as err:
print("shouts cache worker error = %s" % (err)) print("shouts cache worker error = %s" % (err))
await asyncio.sleep(TopShouts.period) await asyncio.sleep(ShoutsCache.period)
@query.field("topViewed") @query.field("topViewed")
async def top_viewed(_, info, limit): async def top_viewed(_, info, limit):
async with TopShouts.lock: async with ShoutsCache.lock:
return TopShouts.top_viewed[:limit] return ShoutsCache.top_viewed[:limit]
@query.field("topMonth") @query.field("topMonth")
async def top_month(_, info, limit): async def top_month(_, info, limit):
async with TopShouts.lock: async with ShoutsCache.lock:
return TopShouts.top_month[:limit] return ShoutsCache.top_month[:limit]
@query.field("topOverall") @query.field("topOverall")
async def top_overall(_, info, limit): async def top_overall(_, info, limit):
async with TopShouts.lock: async with ShoutsCache.lock:
return TopShouts.top_overall[:limit] return ShoutsCache.top_overall[:limit]
@query.field("recents") @query.field("recents")
async def recent_shouts(_, info, limit): async def recent_shouts(_, info, limit):
async with TopShouts.lock: async with ShoutsCache.lock:
return TopShouts.recent_shouts[:limit] return ShoutsCache.recent_shouts[:limit]
@query.field("topAuthors") @query.field("topAuthors")
async def top_authors(_, info, limit): async def top_authors(_, info, limit):
async with TopShouts.lock: async with ShoutsCache.lock:
return TopShouts.top_authors[:limit] return ShoutsCache.top_authors[:limit]
@mutation.field("createShout") @mutation.field("createShout")