add shout stat
This commit is contained in:
parent
944af4e96c
commit
26e903d4f2
3
main.py
3
main.py
|
@ -15,7 +15,7 @@ from redis import redis
|
|||
from resolvers.base import resolvers
|
||||
from resolvers.zine import GitTask, ShoutsCache
|
||||
|
||||
from orm.shout import ShoutViewStorage, TopicStat, ShoutAuthorStorage
|
||||
from orm.shout import ShoutViewStorage, TopicStat, ShoutAuthorStorage, CommentStat
|
||||
|
||||
import asyncio
|
||||
|
||||
|
@ -34,6 +34,7 @@ async def start_up():
|
|||
view_storage_task = asyncio.create_task(ShoutViewStorage.worker())
|
||||
shout_author_task = asyncio.create_task(ShoutAuthorStorage.worker())
|
||||
topic_stat_task = asyncio.create_task(TopicStat.worker())
|
||||
comment_stat_task = asyncio.create_task(CommentStat.worker())
|
||||
|
||||
async def shutdown():
|
||||
await redis.disconnect()
|
||||
|
|
45
orm/shout.py
45
orm/shout.py
|
@ -1,6 +1,6 @@
|
|||
from typing import List
|
||||
from datetime import datetime, timedelta
|
||||
from sqlalchemy import Table, Column, Integer, String, ForeignKey, DateTime, Boolean
|
||||
from sqlalchemy import Table, Column, Integer, String, ForeignKey, DateTime, Boolean, func
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm.attributes import flag_modified
|
||||
from orm import Permission, User, Topic, TopicSubscription
|
||||
|
@ -204,6 +204,7 @@ class TopicStat:
|
|||
else:
|
||||
self.subs_by_topic[topic] = [user]
|
||||
|
||||
@staticmethod
|
||||
async def get_shouts(topic):
|
||||
self = TopicStat
|
||||
async with self.lock:
|
||||
|
@ -277,6 +278,40 @@ class ShoutAuthorStorage:
|
|||
print("ShoutAuthorStorage worker: error = %s" % (err))
|
||||
await asyncio.sleep(self.period)
|
||||
|
||||
class CommentStat:
|
||||
stat_by_topic = {}
|
||||
lock = asyncio.Lock()
|
||||
|
||||
period = 30*60 #sec
|
||||
|
||||
@staticmethod
|
||||
async def load(session):
|
||||
self = CommentStat
|
||||
|
||||
stats = session.query(Comment.shout, func.count(Comment.id).label("count")).\
|
||||
group_by(Comment.shout)
|
||||
self.stat_by_topic = dict([(stat.shout, stat.count) for stat in stats])
|
||||
|
||||
@staticmethod
|
||||
async def get_stat(shout):
|
||||
self = CommentStat
|
||||
async with self.lock:
|
||||
return self.stat_by_topic.get(shout, 0)
|
||||
|
||||
@staticmethod
|
||||
async def worker():
|
||||
self = CommentStat
|
||||
print("CommentStat worker start")
|
||||
while True:
|
||||
try:
|
||||
print("CommentStat worker: load stat")
|
||||
with local_session() as session:
|
||||
async with self.lock:
|
||||
await self.load(session)
|
||||
except Exception as err:
|
||||
print("CommentStat worker: error = %s" % (err))
|
||||
await asyncio.sleep(self.period)
|
||||
|
||||
class Shout(Base):
|
||||
__tablename__ = 'shout'
|
||||
|
||||
|
@ -301,3 +336,11 @@ class Shout(Base):
|
|||
topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__)
|
||||
mainTopic = Column(ForeignKey("topic.slug"), nullable=True)
|
||||
visibleFor = relationship(lambda: User, secondary=ShoutViewer.__tablename__)
|
||||
|
||||
@property
|
||||
async def stat(self):
|
||||
return {
|
||||
"views": await ShoutViewStorage.get_view(self.slug),
|
||||
"comments": await CommentStat.get_stat(self.slug),
|
||||
"ratings": await ShoutRatingStorage.get_total_rating(self.slug)
|
||||
}
|
||||
|
|
|
@ -88,7 +88,6 @@ class ShoutsCache:
|
|||
for row in session.execute(stmt):
|
||||
shout = row.Shout
|
||||
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
|
||||
shout.views = await ShoutViewStorage.get_view(shout.slug)
|
||||
shouts.append(shout)
|
||||
async with ShoutsCache.lock:
|
||||
ShoutsCache.recent_shouts = shouts
|
||||
|
@ -108,7 +107,6 @@ class ShoutsCache:
|
|||
for row in session.execute(stmt):
|
||||
shout = row.Shout
|
||||
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
|
||||
shout.views = await ShoutViewStorage.get_view(shout.slug)
|
||||
shouts.append(shout)
|
||||
async with ShoutsCache.lock:
|
||||
ShoutsCache.top_overall = shouts
|
||||
|
@ -128,7 +126,6 @@ class ShoutsCache:
|
|||
for row in session.execute(stmt):
|
||||
shout = row.Shout
|
||||
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
|
||||
shout.views = await ShoutViewStorage.get_view(shout.slug)
|
||||
shouts.append(shout)
|
||||
async with ShoutsCache.lock:
|
||||
ShoutsCache.top_month = shouts
|
||||
|
@ -336,7 +333,6 @@ async def get_shout_by_slug(_, info, slug):
|
|||
return {} #TODO return error field
|
||||
|
||||
shout.ratings = await ShoutRatingStorage.get_ratings(slug)
|
||||
shout.views = await ShoutViewStorage.get_view(slug)
|
||||
return shout
|
||||
|
||||
@query.field("getShoutComments")
|
||||
|
|
|
@ -307,8 +307,6 @@ type Shout {
|
|||
community: Int
|
||||
cover: String
|
||||
layout: String
|
||||
rating: Int
|
||||
views: Int
|
||||
# replyTo: Shout
|
||||
versionOf: Shout
|
||||
tags: [String] # actual values
|
||||
|
@ -322,6 +320,14 @@ type Shout {
|
|||
deletedBy: Int
|
||||
publishedBy: Int # if there is no published field - it is not published
|
||||
publishedAt: DateTime
|
||||
|
||||
stat: ShoutStat
|
||||
}
|
||||
|
||||
type ShoutStat {
|
||||
views: Int!
|
||||
comments: Int!
|
||||
ratings: Int!
|
||||
}
|
||||
|
||||
type Community {
|
||||
|
|
Loading…
Reference in New Issue
Block a user