From d6eb16a398a8d3a2f58399fd40df7f212680cab0 Mon Sep 17 00:00:00 2001 From: Michael Manfre Date: Mon, 5 Dec 2022 12:55:30 -0500 Subject: Added caching and initial settings --- core/decorators.py | 41 +++++++++++++++++++++++++++++++++++++++++ core/middleware.py | 12 +++++++++++- core/models/config.py | 5 +++++ core/views.py | 3 +++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 core/decorators.py (limited to 'core') diff --git a/core/decorators.py b/core/decorators.py new file mode 100644 index 0000000..4934b60 --- /dev/null +++ b/core/decorators.py @@ -0,0 +1,41 @@ +from functools import partial, wraps + +from django.views.decorators.cache import cache_page as dj_cache_page + +from core.models import Config + + +def cache_page( + timeout: int | str = "cache_timeout_page_default", + *, + per_identity: bool = False, + key_prefix: str = "", +): + """ + Decorator for views that caches the page result. + timeout can either be the number of seconds or the name of a SystemOptions + value. + """ + if isinstance(timeout, str): + timeout = Config.lazy_system_value(timeout) + + def decorator(function): + @wraps(function) + def inner(request, *args, **kwargs): + prefix = key_prefix + if per_identity: + identity_id = request.identity.pk if request.identity else "0" + prefix = f"{key_prefix or ''}:ident{identity_id}" + _timeout = timeout + if callable(_timeout): + _timeout = _timeout() + return dj_cache_page(timeout=_timeout, key_prefix=prefix)(function)( + request, *args, **kwargs + ) + + return inner + + return decorator + + +per_identity_cache_page = partial(cache_page, per_identity=True) diff --git a/core/middleware.py b/core/middleware.py index 08c28fa..bd89d1c 100644 --- a/core/middleware.py +++ b/core/middleware.py @@ -1,3 +1,5 @@ +from time import time + from django.core.exceptions import MiddlewareNotUsed from core import sentry @@ -9,11 +11,19 @@ class ConfigLoadingMiddleware: Caches the system config every request """ + refresh_interval: float = 30.0 + def __init__(self, get_response): self.get_response = get_response + self.config_ts: float = 0.0 def __call__(self, request): - Config.system = Config.load_system() + if ( + not getattr(Config, "system", None) + or (time() - self.config_ts) >= self.refresh_interval + ): + Config.system = Config.load_system() + self.config_ts = time() response = self.get_response(request) return response diff --git a/core/models/config.py b/core/models/config.py index dd7da9f..b18471e 100644 --- a/core/models/config.py +++ b/core/models/config.py @@ -218,6 +218,11 @@ class Config(models.Model): hashtag_unreviewed_are_public: bool = True hashtag_stats_max_age: int = 60 * 60 + cache_timeout_page_default: int = 60 + cache_timeout_page_timeline: int = 60 * 3 + cache_timeout_page_post: int = 60 * 2 + cache_timeout_identity_feed: int = 60 * 5 + restricted_usernames: str = "admin\nadmins\nadministrator\nadministrators\nsystem\nroot\nannounce\nannouncement\nannouncements" class UserOptions(pydantic.BaseModel): diff --git a/core/views.py b/core/views.py index 889fa27..ea8a1ca 100644 --- a/core/views.py +++ b/core/views.py @@ -1,8 +1,10 @@ from django.http import JsonResponse from django.templatetags.static import static +from django.utils.decorators import method_decorator from django.views.generic import TemplateView, View from activities.views.timelines import Home +from core.decorators import cache_page from users.models import Identity @@ -13,6 +15,7 @@ def homepage(request): return LoggedOutHomepage.as_view()(request) +@method_decorator(cache_page(), name="dispatch") class LoggedOutHomepage(TemplateView): template_name = "index.html" -- cgit v1.2.3