From b04d3da7a904d1474019f2f9f5af01c40de5d75b Mon Sep 17 00:00:00 2001
From: Taha Cherfia <taha.cherfia@holi.team>
Date: Wed, 12 Feb 2025 19:18:48 +0100
Subject: [PATCH] NOISSUE: add caching to feed queries

---
 feed_posts/schema/feed_queries.py   | 18 ++++++++++++++++--
 openbook_insights/schema/queries.py | 19 ++++++++++++++++++-
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/feed_posts/schema/feed_queries.py b/feed_posts/schema/feed_queries.py
index 085191942..cb56b78d4 100644
--- a/feed_posts/schema/feed_queries.py
+++ b/feed_posts/schema/feed_queries.py
@@ -8,6 +8,7 @@ from django.db import models
 from django.db.models import Count, OuterRef, Subquery
 from django.db.models.functions import Coalesce
 from django.utils import timezone
+from django.core.cache import cache
 
 from comments.models import Comment
 from feed_posts.enums import VisibilityLevel
@@ -50,6 +51,12 @@ class Query:
     ) -> Paged[FeedItem]:
         user = info.context.request.user
 
+        # Generate cache key based on user and pagination
+        cache_key = f"feed:{user.id if user.is_authenticated else 'anon'}:o{offset}:l{limit}"
+        cached_feed = cache.get(cache_key)
+        if cached_feed:
+            return cached_feed
+
         feed_post_content_type = ContentType.objects.get_for_model(FeedPostModel)
         space_post_content_type = ContentType.objects.get_for_model(PostModel)
 
@@ -110,7 +117,11 @@ class Query:
 
             posts = sorted_posts + list(space_posts)
             feed_items = [map_to_feed_item(post) for post in posts]
-            return paginate_posts(feed_items, offset, limit)
+            result = paginate_posts(feed_items, offset, limit)
+
+            # Cache anonymous results for 10 minutes
+            cache.set(cache_key, result, 600)
+            return result
 
         # Authenticated users
 
@@ -190,5 +201,8 @@ class Query:
 
         posts = list(all_posts.keys())
         feed_items = [map_to_feed_item(post) for post in posts]
+        result = paginate_posts(feed_items, offset, limit)
 
-        return paginate_posts(feed_items, offset, limit)
+        # Cache authenticated user results for 2 minutes
+        cache.set(cache_key, result, 120)
+        return result
diff --git a/openbook_insights/schema/queries.py b/openbook_insights/schema/queries.py
index f2f43d19a..25d763dd0 100644
--- a/openbook_insights/schema/queries.py
+++ b/openbook_insights/schema/queries.py
@@ -1,6 +1,7 @@
 import uuid
-from datetime import datetime
+from datetime import datetime, timedelta
 from typing import Optional
+from django.utils import timezone
 
 import strawberry
 import strawberry_django
@@ -16,6 +17,7 @@ from openbook_insights.models import Insight as InsightModel
 from openbook_insights.schema.types import Insight
 from openbook_insights.schema.types.discussion import Discussion
 from openbook_insights.schema.types.insight import InsightPreview
+from django.core.cache import cache
 
 
 @strawberry.type
@@ -58,6 +60,12 @@ class Query:
     def feed_insights(self, info, offset: int = 0, limit: int = 10) -> Paged[InsightPreview]:
         current_user = info.context.request.user
 
+        # Generate cache key based on pagination
+        cache_key = f"feed_insights:o{offset}:l{limit}"
+        cached_insights = cache.get(cache_key)
+        if cached_insights:
+            return cached_insights
+
         base_queryset = InsightModel.objects.filter(
             Q(creator__isnull=True) | UserModel.is_visible_ignore_blocked_query("creator"),
             date_published__lte=datetime.now(),
@@ -73,6 +81,15 @@ class Query:
             limit,
         )
 
+        # Calculate seconds until next 10am
+        now = timezone.now()
+        next_10am = now.replace(hour=10, minute=0, second=0, microsecond=0)
+        if now.hour >= 10:
+            next_10am += timedelta(days=1)
+        cache_ttl = int((next_10am - now).total_seconds())
+
+        # Cache until next 10am
+        cache.set(cache_key, paged_insights, cache_ttl)
         return paged_insights
 
     @strawberry_django.field()
-- 
GitLab