mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
caching strategy scaled back significantly
This commit is contained in:
parent
094708f396
commit
606024494d
6 changed files with 16 additions and 34 deletions
|
@ -13,7 +13,7 @@ from app.models import User, Community, CommunityJoinRequest, CommunityMember, C
|
||||||
PostReply, Instance, PostVote, PostReplyVote, File, AllowedInstances, BannedInstances
|
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, \
|
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, \
|
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, \
|
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
|
domain_from_url, markdown_to_html, community_membership, ap_datetime
|
||||||
import werkzeug.exceptions
|
import werkzeug.exceptions
|
||||||
|
@ -138,7 +138,6 @@ def lemmy_federated_instances():
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/u/<actor>', methods=['GET'])
|
@bp.route('/u/<actor>', methods=['GET'])
|
||||||
@cache.cached(timeout=10, make_cache_key=cache_key_by_ap_header)
|
|
||||||
def user_profile(actor):
|
def user_profile(actor):
|
||||||
""" Requests to this endpoint can be for a JSON representation of the user, or a HTML rendering of their profile.
|
""" 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 """
|
The two types of requests are differentiated by the header """
|
||||||
|
@ -898,7 +897,6 @@ def community_outbox(actor):
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/c/<actor>/moderators', methods=['GET'])
|
@bp.route('/c/<actor>/moderators', methods=['GET'])
|
||||||
@cache.cached(timeout=10, make_cache_key=cache_key_by_ap_header)
|
|
||||||
def community_moderators(actor):
|
def community_moderators(actor):
|
||||||
actor = actor.strip()
|
actor = actor.strip()
|
||||||
community = Community.query.filter_by(name=actor, banned=False, ap_id=None).first()
|
community = Community.query.filter_by(name=actor, banned=False, ap_id=None).first()
|
||||||
|
@ -945,7 +943,6 @@ def inbox(actor):
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/comment/<int:comment_id>', methods=['GET'])
|
@bp.route('/comment/<int:comment_id>', methods=['GET'])
|
||||||
@cache.cached(timeout=10, make_cache_key=cache_key_by_ap_header)
|
|
||||||
def comment_ap(comment_id):
|
def comment_ap(comment_id):
|
||||||
if is_activitypub_request():
|
if is_activitypub_request():
|
||||||
reply = PostReply.query.get_or_404(comment_id)
|
reply = PostReply.query.get_or_404(comment_id)
|
||||||
|
@ -985,7 +982,6 @@ def comment_ap(comment_id):
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/post/<int:post_id>', methods=['GET', 'POST'])
|
@bp.route('/post/<int:post_id>', methods=['GET', 'POST'])
|
||||||
@cache.cached(timeout=10, make_cache_key=cache_key_by_ap_header)
|
|
||||||
def post_ap(post_id):
|
def post_ap(post_id):
|
||||||
if request.method == 'GET' and is_activitypub_request():
|
if request.method == 'GET' and is_activitypub_request():
|
||||||
post = Post.query.get_or_404(post_id)
|
post = Post.query.get_or_404(post_id)
|
||||||
|
|
|
@ -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', '')
|
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():
|
def lemmy_site_data():
|
||||||
data = {
|
data = {
|
||||||
"site_view": {
|
"site_view": {
|
||||||
|
|
|
@ -91,7 +91,7 @@ def show_community(community: Community):
|
||||||
|
|
||||||
# If nothing has changed since their last visit, return HTTP 304
|
# If nothing has changed since their last visit, return HTTP 304
|
||||||
current_etag = f"{community.id}_{hash(community.last_active)}"
|
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)
|
return return_304(current_etag)
|
||||||
|
|
||||||
mods = community.moderators()
|
mods = community.moderators()
|
||||||
|
|
|
@ -36,7 +36,6 @@ class File(db.Model):
|
||||||
thumbnail_width = db.Column(db.Integer)
|
thumbnail_width = db.Column(db.Integer)
|
||||||
thumbnail_height = db.Column(db.Integer)
|
thumbnail_height = db.Column(db.Integer)
|
||||||
|
|
||||||
@cache.memoize(timeout=500)
|
|
||||||
def view_url(self):
|
def view_url(self):
|
||||||
if self.source_url:
|
if self.source_url:
|
||||||
return self.source_url
|
return self.source_url
|
||||||
|
@ -46,7 +45,6 @@ class File(db.Model):
|
||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
@cache.memoize(timeout=500)
|
|
||||||
def thumbnail_url(self):
|
def thumbnail_url(self):
|
||||||
thumbnail_path = self.thumbnail_path[4:] if self.thumbnail_path.startswith('app/') else self.thumbnail_path
|
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}"
|
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)
|
ignore_bots = db.Column(db.Boolean, default=False)
|
||||||
unread_notifications = db.Column(db.Integer, default=0)
|
unread_notifications = db.Column(db.Integer, default=0)
|
||||||
|
|
||||||
avatar = db.relationship('File', foreign_keys=[avatar_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', foreign_keys=[cover_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_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
|
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:
|
else:
|
||||||
return '[deleted]'
|
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:
|
def avatar_image(self) -> str:
|
||||||
if self.avatar_id is not None:
|
if self.avatar_id is not None:
|
||||||
if self.avatar.file_path 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 self.avatar.source_url
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
@cache.memoize(timeout=500)
|
|
||||||
def cover_image(self) -> str:
|
def cover_image(self) -> str:
|
||||||
if self.cover_id is not None:
|
if self.cover_id is not None:
|
||||||
if self.cover.file_path 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]
|
return self.url[vpos + 2:vpos + 13]
|
||||||
|
|
||||||
def profile_id(self):
|
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):
|
def flush_cache(self):
|
||||||
cache.delete(f'/post/{self.id}_False')
|
cache.delete(f'/post/{self.id}_False')
|
||||||
|
|
|
@ -26,7 +26,7 @@ def show_post(post_id: int):
|
||||||
|
|
||||||
# If nothing has changed since their last visit, return HTTP 304
|
# If nothing has changed since their last visit, return HTTP 304
|
||||||
current_etag = f"{post.id}_{hash(post.last_active)}"
|
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)
|
return return_304(current_etag)
|
||||||
|
|
||||||
mods = post.community.moderators()
|
mods = post.community.moderators()
|
||||||
|
@ -99,10 +99,8 @@ def show_post(post_id: int):
|
||||||
try:
|
try:
|
||||||
message = HttpSignature.signed_request(post.community.ap_inbox_url, create_json, current_user.private_key,
|
message = HttpSignature.signed_request(post.community.ap_inbox_url, create_json, current_user.private_key,
|
||||||
current_user.ap_profile_id + '#main-key')
|
current_user.ap_profile_id + '#main-key')
|
||||||
if message.status_code == 200:
|
if message.status_code != 200:
|
||||||
flash('Your reply has been sent to ' + post.community.title)
|
flash('Failed to send to remote instance', 'warning')
|
||||||
else:
|
|
||||||
flash('Response status code was not 200', 'warning')
|
|
||||||
current_app.logger.error('Response code for reply attempt was ' +
|
current_app.logger.error('Response code for reply attempt was ' +
|
||||||
str(message.status_code) + ' ' + message.text)
|
str(message.status_code) + ' ' + message.text)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
|
@ -335,9 +333,7 @@ def add_reply(post_id: int, comment_id: int):
|
||||||
try:
|
try:
|
||||||
message = HttpSignature.signed_request(post.community.ap_inbox_url, create_json, current_user.private_key,
|
message = HttpSignature.signed_request(post.community.ap_inbox_url, create_json, current_user.private_key,
|
||||||
current_user.ap_profile_id + '#main-key')
|
current_user.ap_profile_id + '#main-key')
|
||||||
if message.status_code == 200:
|
if message.status_code != 200:
|
||||||
flash('Your reply has been sent to ' + post.community.title)
|
|
||||||
else:
|
|
||||||
flash('Response status code was not 200', 'warning')
|
flash('Response status code was not 200', 'warning')
|
||||||
current_app.logger.error('Response code for reply attempt was ' +
|
current_app.logger.error('Response code for reply attempt was ' +
|
||||||
str(message.status_code) + ' ' + message.text)
|
str(message.status_code) + ' ' + message.text)
|
||||||
|
|
|
@ -29,9 +29,10 @@ def render_template(template_name: str, **context) -> Response:
|
||||||
|
|
||||||
# Browser caching using ETags and Cache-Control
|
# Browser caching using ETags and Cache-Control
|
||||||
resp = make_response(content)
|
resp = make_response(content)
|
||||||
if 'etag' in context:
|
if current_user.is_anonymous:
|
||||||
resp.headers.add_header('ETag', context['etag'])
|
if 'etag' in context:
|
||||||
resp.headers.add_header('Cache-Control', 'no-cache, max-age=600, must-revalidate')
|
resp.headers.add_header('ETag', context['etag'])
|
||||||
|
resp.headers.add_header('Cache-Control', 'no-cache, max-age=600, must-revalidate')
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue