From b2acd5cb94d0a675272048c1a3628152648911c1 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 7 Oct 2010 19:33:52 -0500 Subject: Store latest news date in memcached This saves two database queries each request, meaning no database hits at all if we are just going to return a 304 response. It also requires adding a post_save signal to ensure our cache is updated with the correct latest news date upon saving a news item. Signed-off-by: Dan McGee --- feeds.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'feeds.py') diff --git a/feeds.py b/feeds.py index c46a8be3..ecb90b68 100644 --- a/feeds.py +++ b/feeds.py @@ -1,13 +1,18 @@ import datetime from django.contrib.syndication.views import Feed +from django.core.cache import cache from django.db.models import Q +from django.db.models.signals import post_save from django.utils.hashcompat import md5_constructor from django.views.decorators.http import condition from main.models import Arch, Repo, Package from news.models import News +CACHE_TIMEOUT = 1800 +CACHE_NEWS_KEY = 'cache_news_latest' + def package_etag(request, *args, **kwargs): latest = Package.objects.latest('last_update') if latest: @@ -79,13 +84,26 @@ class PackageFeed(Feed): def retrieve_news_latest(): + latest = cache.get(CACHE_NEWS_KEY) + if latest: + return latest try: - latest = News.objects.values('last_modified').latest('last_modified') - return latest['last_modified'] + latest = News.objects.values('last_modified').latest( + 'last_modified')['last_modified'] + cache.set(CACHE_NEWS_KEY, latest, CACHE_TIMEOUT) + return latest except News.DoesNotExist: pass return None +def refresh_news_latest(**kwargs): + # We could delete the value, but that could open a race condition + # where the new data wouldn't have been committed yet by the calling + # thread. Update it instead. + latest = News.objects.values('last_modified').latest( + 'last_modified')['last_modified'] + cache.set(CACHE_NEWS_KEY, latest, CACHE_TIMEOUT) + def news_etag(request, *args, **kwargs): latest = retrieve_news_latest() if latest: @@ -116,4 +134,7 @@ class NewsFeed(Feed): def item_author_name(self, item): return item.author.get_full_name() +# connect signals needed to keep cache in line with reality +post_save.connect(refresh_news_latest, sender=News) + # vim: set ts=4 sw=4 et: -- cgit v1.2.3-55-g3dc8