From 606024494d4d67bd4bcd8ad2a52b639b67fdf8f3 Mon Sep 17 00:00:00 2001 From: rimu <3310831+rimu@users.noreply.github.com> Date: Mon, 11 Dec 2023 20:46:38 +1300 Subject: [PATCH] caching strategy scaled back significantly --- app/activitypub/routes.py | 6 +----- app/activitypub/util.py | 5 ----- app/community/routes.py | 2 +- app/models.py | 18 ++++++------------ app/post/routes.py | 12 ++++-------- app/utils.py | 7 ++++--- 6 files changed, 16 insertions(+), 34 deletions(-) diff --git a/app/activitypub/routes.py b/app/activitypub/routes.py index b1668107..fdd50b7a 100644 --- a/app/activitypub/routes.py +++ b/app/activitypub/routes.py @@ -13,7 +13,7 @@ from app.models import User, Community, CommunityJoinRequest, CommunityMember, C PostReply, Instance, PostVote, PostReplyVote, File, AllowedInstances, BannedInstances from app.activitypub.util import public_key, users_total, active_half_year, active_month, local_posts, local_comments, \ post_to_activity, find_actor_or_create, default_context, instance_blocked, find_reply_parent, find_liked_object, \ - lemmy_site_data, instance_weight, cache_key_by_ap_header, is_activitypub_request + lemmy_site_data, instance_weight, is_activitypub_request from app.utils import gibberish, get_setting, is_image_url, allowlist_html, html_to_markdown, render_template, \ domain_from_url, markdown_to_html, community_membership, ap_datetime import werkzeug.exceptions @@ -138,7 +138,6 @@ def lemmy_federated_instances(): @bp.route('/u/', methods=['GET']) -@cache.cached(timeout=10, make_cache_key=cache_key_by_ap_header) def user_profile(actor): """ Requests to this endpoint can be for a JSON representation of the user, or a HTML rendering of their profile. The two types of requests are differentiated by the header """ @@ -898,7 +897,6 @@ def community_outbox(actor): @bp.route('/c//moderators', methods=['GET']) -@cache.cached(timeout=10, make_cache_key=cache_key_by_ap_header) def community_moderators(actor): actor = actor.strip() community = Community.query.filter_by(name=actor, banned=False, ap_id=None).first() @@ -945,7 +943,6 @@ def inbox(actor): @bp.route('/comment/', methods=['GET']) -@cache.cached(timeout=10, make_cache_key=cache_key_by_ap_header) def comment_ap(comment_id): if is_activitypub_request(): reply = PostReply.query.get_or_404(comment_id) @@ -985,7 +982,6 @@ def comment_ap(comment_id): @bp.route('/post/', methods=['GET', 'POST']) -@cache.cached(timeout=10, make_cache_key=cache_key_by_ap_header) def post_ap(post_id): if request.method == 'GET' and is_activitypub_request(): post = Post.query.get_or_404(post_id) diff --git a/app/activitypub/util.py b/app/activitypub/util.py index 42758e13..7a176f11 100644 --- a/app/activitypub/util.py +++ b/app/activitypub/util.py @@ -409,11 +409,6 @@ def is_activitypub_request(): return 'application/ld+json' in request.headers.get('Accept', '') or 'application/activity+json' in request.headers.get('Accept', '') -# differentiate between cached JSON and cached HTML by appending is_activitypub_request() to the cache key -def cache_key_by_ap_header(**kwargs): - return request.path + "_" + str(is_activitypub_request()) - - def lemmy_site_data(): data = { "site_view": { diff --git a/app/community/routes.py b/app/community/routes.py index 980ea9b8..dcc3c3bf 100644 --- a/app/community/routes.py +++ b/app/community/routes.py @@ -91,7 +91,7 @@ def show_community(community: Community): # If nothing has changed since their last visit, return HTTP 304 current_etag = f"{community.id}_{hash(community.last_active)}" - if request_etag_matches(current_etag): + if current_user.is_anonymous and request_etag_matches(current_etag): return return_304(current_etag) mods = community.moderators() diff --git a/app/models.py b/app/models.py index 5905881e..e22bc9cc 100644 --- a/app/models.py +++ b/app/models.py @@ -36,7 +36,6 @@ class File(db.Model): thumbnail_width = db.Column(db.Integer) thumbnail_height = db.Column(db.Integer) - @cache.memoize(timeout=500) def view_url(self): if self.source_url: return self.source_url @@ -46,7 +45,6 @@ class File(db.Model): else: return '' - @cache.memoize(timeout=500) def thumbnail_url(self): thumbnail_path = self.thumbnail_path[4:] if self.thumbnail_path.startswith('app/') else self.thumbnail_path return f"https://{current_app.config['SERVER_NAME']}/{thumbnail_path}" @@ -213,8 +211,8 @@ class User(UserMixin, db.Model): ignore_bots = db.Column(db.Boolean, default=False) unread_notifications = db.Column(db.Integer, default=0) - avatar = db.relationship('File', foreign_keys=[avatar_id], single_parent=True, cascade="all, delete-orphan") - cover = db.relationship('File', foreign_keys=[cover_id], single_parent=True, cascade="all, delete-orphan") + avatar = db.relationship('File', lazy='joined', foreign_keys=[avatar_id], single_parent=True, cascade="all, delete-orphan") + cover = db.relationship('File', lazy='joined', foreign_keys=[cover_id], single_parent=True, cascade="all, delete-orphan") ap_id = db.Column(db.String(255), index=True) # e.g. username@server ap_profile_id = db.Column(db.String(255), index=True) # e.g. https://server/u/username @@ -253,12 +251,6 @@ class User(UserMixin, db.Model): else: return '[deleted]' - def avatar(self, size): - digest = md5(self.email.lower().encode('utf-8')).hexdigest() - return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format( - digest, size) - - @cache.memoize(timeout=500) def avatar_image(self) -> str: if self.avatar_id is not None: if self.avatar.file_path is not None: @@ -273,7 +265,6 @@ class User(UserMixin, db.Model): return self.avatar.source_url return '' - @cache.memoize(timeout=500) def cover_image(self) -> str: if self.cover_id is not None: if self.cover.file_path is not None: @@ -473,7 +464,10 @@ class Post(db.Model): return self.url[vpos + 2:vpos + 13] def profile_id(self): - return f"https://{current_app.config['SERVER_NAME']}/post/{self.id}" + if self.ap_id: + return self.ap_id + else: + return f"https://{current_app.config['SERVER_NAME']}/post/{self.id}" def flush_cache(self): cache.delete(f'/post/{self.id}_False') diff --git a/app/post/routes.py b/app/post/routes.py index 106265f5..00b0c636 100644 --- a/app/post/routes.py +++ b/app/post/routes.py @@ -26,7 +26,7 @@ def show_post(post_id: int): # If nothing has changed since their last visit, return HTTP 304 current_etag = f"{post.id}_{hash(post.last_active)}" - if request_etag_matches(current_etag): + if current_user.is_anonymous and request_etag_matches(current_etag): return return_304(current_etag) mods = post.community.moderators() @@ -99,10 +99,8 @@ def show_post(post_id: int): try: message = HttpSignature.signed_request(post.community.ap_inbox_url, create_json, current_user.private_key, current_user.ap_profile_id + '#main-key') - if message.status_code == 200: - flash('Your reply has been sent to ' + post.community.title) - else: - flash('Response status code was not 200', 'warning') + if message.status_code != 200: + flash('Failed to send to remote instance', 'warning') current_app.logger.error('Response code for reply attempt was ' + str(message.status_code) + ' ' + message.text) except Exception as ex: @@ -335,9 +333,7 @@ def add_reply(post_id: int, comment_id: int): try: message = HttpSignature.signed_request(post.community.ap_inbox_url, create_json, current_user.private_key, current_user.ap_profile_id + '#main-key') - if message.status_code == 200: - flash('Your reply has been sent to ' + post.community.title) - else: + if message.status_code != 200: flash('Response status code was not 200', 'warning') current_app.logger.error('Response code for reply attempt was ' + str(message.status_code) + ' ' + message.text) diff --git a/app/utils.py b/app/utils.py index d39e27f0..742262c2 100644 --- a/app/utils.py +++ b/app/utils.py @@ -29,9 +29,10 @@ def render_template(template_name: str, **context) -> Response: # Browser caching using ETags and Cache-Control resp = make_response(content) - if 'etag' in context: - resp.headers.add_header('ETag', context['etag']) - resp.headers.add_header('Cache-Control', 'no-cache, max-age=600, must-revalidate') + if current_user.is_anonymous: + if 'etag' in context: + resp.headers.add_header('ETag', context['etag']) + resp.headers.add_header('Cache-Control', 'no-cache, max-age=600, must-revalidate') return resp