add topic stat

This commit is contained in:
knst-kotov 2021-12-13 19:51:01 +03:00
parent 5a47951b66
commit ab9990a616
4 changed files with 60 additions and 2 deletions

View File

@ -15,7 +15,7 @@ from redis import redis
from resolvers.base import resolvers
from resolvers.zine import GitTask, ShoutsCache
from orm.shout import ShoutViewStorage
from orm.shout import ShoutViewStorage, TopicStat
import asyncio
@ -32,6 +32,7 @@ async def start_up():
git_task = asyncio.create_task(GitTask.git_task_worker())
shouts_cache_task = asyncio.create_task(ShoutsCache.worker())
view_storage_task = asyncio.create_task(ShoutViewStorage.worker())
topic_stat_task = asyncio.create_task(TopicStat.worker())
async def shutdown():
await redis.disconnect()

View File

@ -140,6 +140,51 @@ class ShoutViewStorage:
print("ShoutViewStorage worker: error = %s" % (err))
await asyncio.sleep(ShoutViewStorage.period)
class TopicStat:
shouts_by_topic = {}
lock = asyncio.Lock()
period = 30*60 #sec
@staticmethod
async def load_stat(session):
self = TopicStat
shout_topics = session.query(ShoutTopic)
for shout_topic in shout_topics:
topic = shout_topic.topic
shout = shout_topic.shout
if topic in self.shouts_by_topic:
self.shouts_by_topic[topic].append(shout)
else:
self.shouts_by_topic[topic] = [shout]
@staticmethod
async def get_stat(topic):
self = TopicStat
async with self.lock:
shouts = self.shouts_by_topic.get(topic, [])
stat = { "shouts" : len(shouts) }
views = 0
for shout in shouts:
views += await ShoutViewStorage.get_view(shout)
stat["views"] = views
return stat
@staticmethod
async def worker():
self = TopicStat
print("TopicStat worker start")
while True:
try:
print("TopicStat worker: load stat")
with local_session() as session:
async with self.lock:
await self.load_stat(session)
except Exception as err:
print("TopicStat worker: error = %s" % (err))
await asyncio.sleep(self.period)
class Shout(Base):
__tablename__ = 'shout'

View File

@ -1,4 +1,5 @@
from orm import Topic, TopicSubscription, TopicStorage, Shout, User
from orm.shout import TopicStat
from orm.base import local_session
from resolvers.base import mutation, query, subscription
from resolvers.zine import ShoutSubscriptions
@ -8,7 +9,12 @@ import asyncio
@query.field("topicsBySlugs")
async def topics_by_slugs(_, info, slugs = None):
with local_session() as session:
return await TopicStorage.get_topics(slugs)
topics = await TopicStorage.get_topics(slugs)
all_fields = [node.name.value for node in info.field_nodes[0].selection_set.selections]
if "topicStat" in all_fields:
for topic in topics:
topic.topicStat = await TopicStat.get_stat(topic.slug)
return topics
@query.field("topicsByCommunity")
async def topics_by_community(_, info, community):

View File

@ -331,6 +331,11 @@ type Community {
pic: String!
}
type TopicStat {
shouts: Int
views: Int
}
type Topic {
slug: String! # ID
title: String
@ -339,6 +344,7 @@ type Topic {
parents: [String] # NOTE: topic can have parent topics
children: [String] # and children
community: String!
topicStat: TopicStat
}
# TODO: resolvers to add/remove topics from publication