update caching on homepage, and add db checks to healthcheck
This commit is contained in:
parent
411c274e56
commit
7d94dc001f
4 changed files with 75 additions and 18 deletions
6
common/context_processors.py
Normal file
6
common/context_processors.py
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
def cache_settings(request):
|
||||||
|
return {
|
||||||
|
'CACHE_TIMEOUT': settings.CACHE_TIMEOUT,
|
||||||
|
}
|
||||||
|
|
@ -148,6 +148,7 @@ TEMPLATES = [
|
||||||
"django.template.context_processors.request",
|
"django.template.context_processors.request",
|
||||||
"django.contrib.auth.context_processors.auth",
|
"django.contrib.auth.context_processors.auth",
|
||||||
"django.contrib.messages.context_processors.messages",
|
"django.contrib.messages.context_processors.messages",
|
||||||
|
"common.context_processors.cache_settings",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -294,6 +295,8 @@ SOCIALACCOUNT_EMAIL_AUTHENTICATION = False
|
||||||
SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = False
|
SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = False
|
||||||
SOCIALACCOUNT_ONLY = False
|
SOCIALACCOUNT_ONLY = False
|
||||||
|
|
||||||
|
CACHE_TIMEOUT = 604800 # 1 week
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
CACHES = {
|
CACHES = {
|
||||||
"default": {
|
"default": {
|
||||||
|
|
@ -305,5 +308,6 @@ else:
|
||||||
"default": {
|
"default": {
|
||||||
"BACKEND": "django.core.cache.backends.db.DatabaseCache",
|
"BACKEND": "django.core.cache.backends.db.DatabaseCache",
|
||||||
"LOCATION": "django_cache",
|
"LOCATION": "django_cache",
|
||||||
|
"TIMEOUT": 604800, # 1 week
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ from django.http import HttpResponseRedirect
|
||||||
import logging
|
import logging
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
import contextlib
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -31,46 +32,54 @@ class HomePageView(TemplateView):
|
||||||
|
|
||||||
# Recent Offers
|
# Recent Offers
|
||||||
try:
|
try:
|
||||||
recent_offers_qs = base_offer_qs.order_by("-created_at")
|
recent_offers_qs = base_offer_qs.order_by("-created_at")[:6]
|
||||||
context["recent_offers"] = recent_offers_qs[:6]
|
context["recent_offers"] = recent_offers_qs
|
||||||
|
context["cache_key_recent_offers"] = f"recent_offers_{recent_offers_qs.values_list('pk', 'updated_at')}"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error fetching recent offers: {str(e)}")
|
logger.error(f"Error fetching recent offers: {str(e)}")
|
||||||
context["recent_offers"] = []
|
context["recent_offers"] = []
|
||||||
|
context["cache_key_recent_offers"] = "recent_offers_error"
|
||||||
|
|
||||||
# Most Offered Cards
|
# Most Offered Cards
|
||||||
try:
|
try:
|
||||||
context["most_offered_cards"] = (
|
most_offered_cards_qs = (
|
||||||
Card.objects.filter(tradeofferhavecard__isnull=False).filter(rarity_level__lte=5)
|
Card.objects.filter(tradeofferhavecard__isnull=False).filter(rarity_level__lte=5)
|
||||||
.annotate(offer_count=Sum("tradeofferhavecard__quantity"))
|
.annotate(offer_count=Sum("tradeofferhavecard__quantity"))
|
||||||
.order_by("-offer_count")[:6]
|
.order_by("-offer_count")[:6]
|
||||||
)
|
)
|
||||||
|
context["most_offered_cards"] = most_offered_cards_qs
|
||||||
|
context["cache_key_most_offered_cards"] = f"most_offered_cards_{most_offered_cards_qs.values_list('pk', 'updated_at')}"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error fetching most offered cards: {str(e)}")
|
logger.error(f"Error fetching most offered cards: {str(e)}")
|
||||||
context["most_offered_cards"] = []
|
context["most_offered_cards"] = []
|
||||||
|
context["cache_key_most_offered_cards"] = "most_offered_cards_error"
|
||||||
# Most Wanted Cards
|
# Most Wanted Cards
|
||||||
try:
|
try:
|
||||||
context["most_wanted_cards"] = (
|
most_wanted_cards_qs = (
|
||||||
Card.objects.filter(tradeofferwantcard__isnull=False).filter(rarity_level__lte=5)
|
Card.objects.filter(tradeofferwantcard__isnull=False).filter(rarity_level__lte=5)
|
||||||
.annotate(offer_count=Sum("tradeofferwantcard__quantity"))
|
.annotate(offer_count=Sum("tradeofferwantcard__quantity"))
|
||||||
.order_by("-offer_count")[:6]
|
.order_by("-offer_count")[:6]
|
||||||
)
|
)
|
||||||
|
context["most_wanted_cards"] = most_wanted_cards_qs
|
||||||
|
context["cache_key_most_wanted_cards"] = f"most_wanted_cards_{most_wanted_cards_qs.values_list('pk', 'updated_at')}"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error fetching most wanted cards: {str(e)}")
|
logger.error(f"Error fetching most wanted cards: {str(e)}")
|
||||||
context["most_wanted_cards"] = []
|
context["most_wanted_cards"] = []
|
||||||
|
|
||||||
# Least Offered Cards
|
# Least Offered Cards
|
||||||
try:
|
try:
|
||||||
context["least_offered_cards"] = (
|
least_offered_cards_qs = (
|
||||||
Card.objects.filter(rarity_level__lte=5).annotate(
|
Card.objects.filter(rarity_level__lte=5).annotate(
|
||||||
offer_count=Coalesce(Sum("tradeofferhavecard__quantity"), 0)
|
offer_count=Coalesce(Sum("tradeofferhavecard__quantity"), 0)
|
||||||
)
|
)
|
||||||
.order_by("offer_count")[:6]
|
.order_by("offer_count")[:6]
|
||||||
)
|
)
|
||||||
|
context["least_offered_cards"] = least_offered_cards_qs
|
||||||
|
context["cache_key_least_offered_cards"] = f"least_offered_cards_{least_offered_cards_qs.values_list('pk', 'updated_at')}"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error fetching least offered cards: {str(e)}")
|
logger.error(f"Error fetching least offered cards: {str(e)}")
|
||||||
context["least_offered_cards"] = []
|
context["least_offered_cards"] = []
|
||||||
|
context["cache_key_least_offered_cards"] = "least_offered_cards_error"
|
||||||
# Build featured offers with custom ordering
|
# Build featured offers with custom ordering
|
||||||
featured = OrderedDict()
|
featured = OrderedDict()
|
||||||
# Featured "All" offers remains fixed at the top
|
# Featured "All" offers remains fixed at the top
|
||||||
|
|
@ -100,10 +109,22 @@ class HomePageView(TemplateView):
|
||||||
logger.error(f"Error processing rarity-based featured offers: {str(e)}")
|
logger.error(f"Error processing rarity-based featured offers: {str(e)}")
|
||||||
|
|
||||||
context["featured_offers"] = featured
|
context["featured_offers"] = featured
|
||||||
|
# Generate a cache key based on the pks and updated_at timestamps of all featured offers
|
||||||
|
all_offer_identifiers = []
|
||||||
|
for section_name,section_offers in featured.items():
|
||||||
|
# featured_section is a QuerySet. Fetch (pk, updated_at) tuples.
|
||||||
|
identifiers = section_offers.values_list('pk', 'updated_at')
|
||||||
|
# Format each tuple as "pk_timestamp" and add to the list
|
||||||
|
section_strings = [f"{section_name}_{pk}_{ts.timestamp()}" for pk, ts in identifiers]
|
||||||
|
all_offer_identifiers.extend(section_strings)
|
||||||
|
|
||||||
|
# Join all identifiers into a single string, sorted for consistency regardless of order
|
||||||
|
combined_identifiers = "|".join(sorted(all_offer_identifiers))
|
||||||
|
context["cache_key_featured_offers"] = f"featured_offers_{combined_identifiers}"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Unhandled error in HomePageView.get_context_data: {str(e)}")
|
logger.error(f"Unhandled error in HomePageView.get_context_data: {str(e)}")
|
||||||
# Provide fallback empty data
|
# Provide fallback empty data
|
||||||
context["cards"] = []
|
context["cards"] = None
|
||||||
context["recent_offers"] = []
|
context["recent_offers"] = []
|
||||||
context["most_offered_cards"] = []
|
context["most_offered_cards"] = []
|
||||||
context["most_wanted_cards"] = []
|
context["most_wanted_cards"] = []
|
||||||
|
|
@ -118,4 +139,27 @@ class HomePageView(TemplateView):
|
||||||
|
|
||||||
class HealthCheckView(View):
|
class HealthCheckView(View):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
|
||||||
|
try:
|
||||||
|
from django.db import connection
|
||||||
|
connection.cursor().execute("SELECT 1")
|
||||||
|
except Exception as e:
|
||||||
|
return HttpResponse("Database connection failed", status=500)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from trades.models import TradeOffer
|
||||||
|
with contextlib.redirect_stdout(None):
|
||||||
|
print(TradeOffer.objects.count())
|
||||||
|
except Exception as e:
|
||||||
|
return HttpResponse("DB models not reachable, but db is reachable", status=500)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from django.core.cache import cache
|
||||||
|
cache.set("test", "test")
|
||||||
|
with contextlib.redirect_stdout(None):
|
||||||
|
print(cache.get("test"))
|
||||||
|
except Exception as e:
|
||||||
|
return HttpResponse("Cache not reachable", status=500)
|
||||||
|
|
||||||
|
logger.info("OK/HEALTHY")
|
||||||
return HttpResponse("OK/HEALTHY")
|
return HttpResponse("OK/HEALTHY")
|
||||||
|
|
|
||||||
|
|
@ -41,44 +41,44 @@
|
||||||
<h2 id="stats-heading" class="text-2xl font-semibold mb-4">Card Stats</h2>
|
<h2 id="stats-heading" class="text-2xl font-semibold mb-4">Card Stats</h2>
|
||||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||||
<!-- Most Offered Cards -->
|
<!-- Most Offered Cards -->
|
||||||
|
{% cache CACHE_TIMEOUT most_offered_cards cache_key_most_offered_cards %}
|
||||||
<div>
|
<div>
|
||||||
<div class="card card-border bg-base-100 shadow-lg">
|
<div class="card card-border bg-base-100 shadow-lg">
|
||||||
<div class="card-header text-base-content p-4">
|
<div class="card-header text-base-content p-4">
|
||||||
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Offered</h5>
|
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Offered</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body my-4 p-0">
|
<div class="card-body my-4 p-0">
|
||||||
{% cache 300 most_offered_cards %}
|
{% include "home/_card_list.html" with cards=most_offered_cards %}
|
||||||
{% include "home/_card_list.html" with cards=most_offered_cards %}
|
|
||||||
{% endcache %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endcache %}
|
||||||
<!-- Most Wanted Cards -->
|
<!-- Most Wanted Cards -->
|
||||||
|
{% cache CACHE_TIMEOUT most_wanted_cards cache_key_most_wanted_cards %}
|
||||||
<div>
|
<div>
|
||||||
<div class="card card-border bg-base-100 shadow-lg">
|
<div class="card card-border bg-base-100 shadow-lg">
|
||||||
<div class="card-header text-base-content p-4">
|
<div class="card-header text-base-content p-4">
|
||||||
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Wanted</h5>
|
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Wanted</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body my-4 p-0">
|
<div class="card-body my-4 p-0">
|
||||||
{% cache 300 most_wanted_cards %}
|
{% include "home/_card_list.html" with cards=most_wanted_cards %}
|
||||||
{% include "home/_card_list.html" with cards=most_wanted_cards %}
|
|
||||||
{% endcache %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endcache %}
|
||||||
<!-- Least Offered Cards (Last Group) -->
|
<!-- Least Offered Cards (Last Group) -->
|
||||||
|
{% cache CACHE_TIMEOUT least_offered_cards cache_key_least_offered_cards %}
|
||||||
<div class="col-span-2 md:col-span-1">
|
<div class="col-span-2 md:col-span-1">
|
||||||
<div class="card card-border bg-base-100 shadow-lg">
|
<div class="card card-border bg-base-100 shadow-lg">
|
||||||
<div class="card-header text-base-content p-4">
|
<div class="card-header text-base-content p-4">
|
||||||
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Least Offered</h5>
|
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Least Offered</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body my-4 p-0">
|
<div class="card-body my-4 p-0">
|
||||||
{% cache 300 least_offered_cards %}
|
{% include "home/_card_list.html" with cards=least_offered_cards %}
|
||||||
{% include "home/_card_list.html" with cards=least_offered_cards %}
|
|
||||||
{% endcache %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endcache %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -86,6 +86,7 @@
|
||||||
<section class="mb-8">
|
<section class="mb-8">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<!-- Featured Offers -->
|
<!-- Featured Offers -->
|
||||||
|
{% cache CACHE_TIMEOUT featured_offers cache_key_featured_offers %}
|
||||||
<div>
|
<div>
|
||||||
<div class="p-4 text-center ">
|
<div class="p-4 text-center ">
|
||||||
<h5 class="text-xl font-semibold whitespace-nowrap truncate mb-0">Featured Offers</h5>
|
<h5 class="text-xl font-semibold whitespace-nowrap truncate mb-0">Featured Offers</h5>
|
||||||
|
|
@ -102,8 +103,9 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endcache %}
|
||||||
<!-- Recent Offers -->
|
<!-- Recent Offers -->
|
||||||
|
{% cache CACHE_TIMEOUT recent_offers cache_key_recent_offers %}
|
||||||
<div>
|
<div>
|
||||||
<div class="text-center p-4">
|
<div class="text-center p-4">
|
||||||
<h5 class="text-xl font-semibold whitespace-nowrap truncate mb-0">Recent Offers</h5>
|
<h5 class="text-xl font-semibold whitespace-nowrap truncate mb-0">Recent Offers</h5>
|
||||||
|
|
@ -118,6 +120,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endcache %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue