cache-updates-fix

This commit is contained in:
Untone 2024-05-05 18:46:16 +03:00
parent c9205a698f
commit f6cb7e18d1
3 changed files with 56 additions and 20 deletions

View File

@ -8,8 +8,11 @@ from orm.rating import is_negative, is_positive
from orm.reaction import Reaction, ReactionKind from orm.reaction import Reaction, ReactionKind
from orm.shout import Shout, ShoutAuthor, ShoutTopic from orm.shout import Shout, ShoutAuthor, ShoutTopic
from orm.topic import Topic from orm.topic import Topic
from orm.author import Author
from resolvers.follower import reactions_follow, reactions_unfollow from resolvers.follower import reactions_follow, reactions_unfollow
from resolvers.stat import get_with_stat
from services.auth import login_required from services.auth import login_required
from services.cache import cache_topic, cache_author
from services.db import local_session from services.db import local_session
from services.diff import apply_diff, get_diff from services.diff import apply_diff, get_diff
from services.logger import root_logger as logger from services.logger import root_logger as logger
@ -18,6 +21,22 @@ from services.schema import mutation, query
from services.search import search_service from services.search import search_service
async def cache_by_id(what: str, entity_id: int):
is_author = what == "AUTHOR"
alias = Author if is_author else Topic
q = select(alias).filter(alias.id == entity_id)
[x] = get_with_stat(q)
if not x:
return
d = x.dict() # convert object to dictionary
if is_author:
await cache_author(d)
else:
await cache_topic(d)
return d
@query.field("get_my_shout") @query.field("get_my_shout")
@login_required @login_required
async def get_my_shout(_, info, shout_id: int): async def get_my_shout(_, info, shout_id: int):
@ -280,6 +299,8 @@ async def update_shout(_, info, shout_id: int, shout_input=None, publish=False):
if topics_input: if topics_input:
patch_topics(session, shout_by_id, topics_input) patch_topics(session, shout_by_id, topics_input)
del shout_input["topics"] del shout_input["topics"]
for tpc in topics_input:
await cache_by_id("TOPIC", tpc["id"])
# main topic # main topic
main_topic = shout_input.get("main_topic") main_topic = shout_input.get("main_topic")
@ -300,6 +321,8 @@ async def update_shout(_, info, shout_id: int, shout_input=None, publish=False):
await notify_shout(shout_dict, "published") await notify_shout(shout_dict, "published")
# search service indexing # search service indexing
search_service.index(shout_by_id) search_service.index(shout_by_id)
for a in shout_by_id.authors:
await cache_by_id("AUTHOR", a.id)
return {"shout": shout_dict, "error": None} return {"shout": shout_dict, "error": None}
else: else:
@ -331,13 +354,18 @@ async def delete_shout(_, info, shout_id: int):
shout_dict = shout.dict() shout_dict = shout.dict()
# NOTE: only owner and editor can mark the shout as deleted # NOTE: only owner and editor can mark the shout as deleted
if shout_dict["created_by"] == author_id or "editor" in roles: if shout_dict["created_by"] == author_id or "editor" in roles:
for author_id in shout.authors:
reactions_unfollow(author_id, shout_id)
shout_dict["deleted_at"] = int(time.time()) shout_dict["deleted_at"] = int(time.time())
Shout.update(shout, shout_dict) Shout.update(shout, shout_dict)
session.add(shout) session.add(shout)
session.commit() session.commit()
for author_id in shout.authors:
reactions_unfollow(author_id, shout_id)
await cache_by_id("AUTHOR", author_id)
for topic_id in shout.topics:
await cache_by_id("TOPIC", topic_id)
await notify_shout(shout_dict, "delete") await notify_shout(shout_dict, "delete")
return {"error": None} return {"error": None}
else: else:

View File

@ -13,7 +13,7 @@ from orm.shout import Shout, ShoutReactionsFollower
from orm.topic import Topic, TopicFollower from orm.topic import Topic, TopicFollower
from resolvers.stat import author_follows_authors, author_follows_topics, get_with_stat from resolvers.stat import author_follows_authors, author_follows_topics, get_with_stat
from services.auth import login_required from services.auth import login_required
from services.cache import DEFAULT_FOLLOWS, cache_follower, cache_topic from services.cache import DEFAULT_FOLLOWS, cache_author, cache_topic
from services.db import local_session from services.db import local_session
from services.logger import root_logger as logger from services.logger import root_logger as logger
from services.notify import notify_follower from services.notify import notify_follower
@ -30,8 +30,10 @@ async def cache_by_slug(what: str, slug: str):
return return
d = x.dict() # convert object to dictionary d = x.dict() # convert object to dictionary
cache_handler = cache_follower if is_author else cache_topic if is_author:
await cache_handler(d) await cache_author(d)
else:
await cache_topic(d)
return d return d
@ -59,12 +61,14 @@ async def follow(_, info, what, slug):
error = author_follow(follower_id, slug) error = author_follow(follower_id, slug)
if not error: if not error:
author_dict = await cache_by_slug(what, slug) author_dict = await cache_by_slug(what, slug)
author_id = author_dict.get("id") if isinstance(author_dict, dict):
follows_ids = [a.id for a in follows] author_id = author_dict.get("id")
if author_id not in follows_ids: if author_id:
await cache_follower(follower_dict, author_dict) follows_ids = [a.id for a in follows]
await notify_follower(follower_dict, author_id, "follow") if author_id not in follows_ids:
follows.append(author_dict) await cache_author(follower_dict)
await notify_follower(follower_dict, author_id, "follow")
follows.append(author_dict)
elif what == "TOPIC": elif what == "TOPIC":
error = topic_follow(follower_id, slug) error = topic_follow(follower_id, slug)
@ -109,13 +113,17 @@ async def unfollow(_, info, what, slug):
if not error: if not error:
logger.info(f"@{follower_dict.get('slug')} unfollowed @{slug}") logger.info(f"@{follower_dict.get('slug')} unfollowed @{slug}")
author_dict = await cache_by_slug(what, slug) author_dict = await cache_by_slug(what, slug)
author_id = author_dict.get("id") if isinstance(author_dict, dict):
for idx, item in enumerate(follows): author_id = author_dict.get("id")
if item["id"] == author_id: if author_id:
await cache_follower(follower_dict, author_dict, False) for idx, item in enumerate(follows):
await notify_follower(follower_dict, author_id, "unfollow") if item["id"] == author_id:
follows.pop(idx) # Remove the author_dict from the follows list await cache_author(follower_dict)
break await notify_follower(follower_dict, author_id, "unfollow")
follows.pop(
idx
) # Remove the author_dict from the follows list
break
elif what == "TOPIC": elif what == "TOPIC":
error = topic_unfollow(follower_id, slug) error = topic_unfollow(follower_id, slug)

View File

@ -123,7 +123,7 @@ async def cache_follower(follower: dict, author: dict, is_insert=True):
return followers return followers
async def cache_topic(topic_dict: str): async def cache_topic(topic_dict: dict):
# update stat all field for followers' caches in <topics> list # update stat all field for followers' caches in <topics> list
followers = ( followers = (
local_session() local_session()