optimize views calculation
This commit is contained in:
parent
a98d5f6ee6
commit
e2c8ceedbf
65
orm/shout.py
65
orm/shout.py
|
@ -85,8 +85,9 @@ class ShoutViewByDay(Base):
|
||||||
|
|
||||||
class ShoutViewStorage:
|
class ShoutViewStorage:
|
||||||
|
|
||||||
views = []
|
view_by_shout = {}
|
||||||
this_day_views = {}
|
this_day_views = {}
|
||||||
|
to_flush = []
|
||||||
|
|
||||||
period = 30*60 #sec
|
period = 30*60 #sec
|
||||||
|
|
||||||
|
@ -95,43 +96,55 @@ class ShoutViewStorage:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def init(session):
|
def init(session):
|
||||||
self = ShoutViewStorage
|
self = ShoutViewStorage
|
||||||
self.views = session.query(ShoutViewByDay).all()
|
views = session.query(ShoutViewByDay).all()
|
||||||
for view in self.views:
|
for view in views:
|
||||||
shout_slug = view.shout
|
shout = view.shout
|
||||||
if not shout_slug in self.this_day_views:
|
value = view.value
|
||||||
self.this_day_views[shout_slug] = view
|
old_value = self.view_by_shout.get(shout, 0)
|
||||||
this_day_view = self.this_day_views[shout_slug]
|
self.view_by_shout[shout] = old_value + value;
|
||||||
|
if not shout in self.this_day_views:
|
||||||
|
self.this_day_views[shout] = view
|
||||||
|
this_day_view = self.this_day_views[shout]
|
||||||
if this_day_view.day < view.day:
|
if this_day_view.day < view.day:
|
||||||
self.this_day_views[shout_slug] = view
|
self.this_day_views[shout] = view
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def get_view(shout_slug):
|
async def get_view(shout_slug):
|
||||||
async with ShoutViewStorage.lock:
|
self = ShoutViewStorage
|
||||||
shout_views = list(filter(lambda x: x.shout == shout_slug, ShoutViewStorage.views))
|
async with self.lock:
|
||||||
return reduce((lambda x, y: x + y.value), shout_views, 0)
|
return self.view_by_shout.get(shout_slug, 0)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def inc_view(shout_slug):
|
async def inc_view(shout_slug):
|
||||||
self = ShoutViewStorage
|
self = ShoutViewStorage
|
||||||
async with ShoutViewStorage.lock:
|
async with self.lock:
|
||||||
this_day_view = self.this_day_views.get(shout_slug)
|
this_day_view = self.this_day_views.get(shout_slug)
|
||||||
day_start = datetime.now().replace(hour = 0, minute = 0, second = 0)
|
day_start = datetime.now().replace(hour = 0, minute = 0, second = 0)
|
||||||
if not this_day_view or this_day_view.day < day_start:
|
if not this_day_view or this_day_view.day < day_start:
|
||||||
|
if this_day_view and getattr(this_day_view, "modified", False):
|
||||||
|
self.to_flush.append(this_day_view)
|
||||||
this_day_view = ShoutViewByDay.create(shout = shout_slug, value = 1)
|
this_day_view = ShoutViewByDay.create(shout = shout_slug, value = 1)
|
||||||
self.this_day_views[shout_slug] = this_day_view
|
self.this_day_views[shout_slug] = this_day_view
|
||||||
self.views.append(this_day_view)
|
|
||||||
else:
|
else:
|
||||||
this_day_view.value = this_day_view.value + 1
|
this_day_view.value = this_day_view.value + 1
|
||||||
this_day_view.modified = True
|
|
||||||
|
this_day_view.modified = True
|
||||||
|
|
||||||
|
old_value = self.view_by_shout.get(shout_slug, 0)
|
||||||
|
self.view_by_shout[shout_slug] = old_value + 1;
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def flush_changes(session):
|
async def flush_changes(session):
|
||||||
async with ShoutViewStorage.lock:
|
self = ShoutViewStorage
|
||||||
for view in ShoutViewStorage.this_day_views.values():
|
async with self.lock:
|
||||||
|
for view in self.this_day_views.values():
|
||||||
if getattr(view, "modified", False):
|
if getattr(view, "modified", False):
|
||||||
session.add(view)
|
session.add(view)
|
||||||
flag_modified(view, "value")
|
flag_modified(view, "value")
|
||||||
view.modified = False
|
view.modified = False
|
||||||
|
for view in self.to_flush:
|
||||||
|
session.add(view)
|
||||||
|
self.to_flush.clear()
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -150,6 +163,7 @@ class TopicStat:
|
||||||
shouts_by_topic = {}
|
shouts_by_topic = {}
|
||||||
authors_by_topic = {}
|
authors_by_topic = {}
|
||||||
subs_by_topic = {}
|
subs_by_topic = {}
|
||||||
|
views_by_topic = {}
|
||||||
lock = asyncio.Lock()
|
lock = asyncio.Lock()
|
||||||
|
|
||||||
period = 30*60 #sec
|
period = 30*60 #sec
|
||||||
|
@ -172,6 +186,9 @@ class TopicStat:
|
||||||
else:
|
else:
|
||||||
self.authors_by_topic[topic] = set(authors)
|
self.authors_by_topic[topic] = set(authors)
|
||||||
|
|
||||||
|
old_views = self.views_by_topic.get(topic, 0)
|
||||||
|
self.views_by_topic[topic] = old_views + await ShoutViewStorage.get_view(shout)
|
||||||
|
|
||||||
subs = session.query(TopicSubscription)
|
subs = session.query(TopicSubscription)
|
||||||
for sub in subs:
|
for sub in subs:
|
||||||
topic = sub.topic
|
topic = sub.topic
|
||||||
|
@ -192,20 +209,16 @@ class TopicStat:
|
||||||
async with self.lock:
|
async with self.lock:
|
||||||
shouts = self.shouts_by_topic.get(topic, [])
|
shouts = self.shouts_by_topic.get(topic, [])
|
||||||
subs = self.subs_by_topic.get(topic, [])
|
subs = self.subs_by_topic.get(topic, [])
|
||||||
authors = self.authors_by_topic.get(topic, set())
|
authors = self.authors_by_topic.get(topic, [])
|
||||||
stat = {
|
views = self.views_by_topic.get(topic, 0)
|
||||||
|
|
||||||
|
return {
|
||||||
"shouts" : len(shouts),
|
"shouts" : len(shouts),
|
||||||
"authors" : len(authors),
|
"authors" : len(authors),
|
||||||
"subscriptions" : len(subs)
|
"subscriptions" : len(subs),
|
||||||
|
"views" : views
|
||||||
}
|
}
|
||||||
|
|
||||||
views = 0
|
|
||||||
for shout in shouts:
|
|
||||||
views += await ShoutViewStorage.get_view(shout)
|
|
||||||
stat["views"] = views
|
|
||||||
|
|
||||||
return stat
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def worker():
|
async def worker():
|
||||||
self = TopicStat
|
self = TopicStat
|
||||||
|
|
Loading…
Reference in New Issue
Block a user