summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2010-10-07 19:33:52 -0500
committerDan McGee <dan@archlinux.org>2010-10-07 19:43:13 -0500
commitb2acd5cb94d0a675272048c1a3628152648911c1 (patch)
tree2ad9102aab22721be9acbf278359069a48e2fb19
parentcf7bf2de294a0e7be37f03935c0a292d60ed1829 (diff)
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 <dan@archlinux.org>
-rw-r--r--feeds.py25
1 files changed, 23 insertions, 2 deletions
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: